Some checks failed
Deploy / deploy (push) Has been cancelled
Profil çerezinin SSR'da kullanılmasını sağlayarak, sonuç sayfasındaki yönlendirmeleri güncelledik. Artık profil bilgileri URL parametreleri yerine çerezden alınarak işleniyor. Ayrıca, profil çerezi olmayan kullanıcılar için yönlendirme mantığı iyileştirildi. Çeşitli bileşenlerdeki URL oluşturma fonksiyonları güncellenerek, profil bilgileri çerezden okunacak şekilde düzenlendi. Bu değişiklikler, kullanıcı deneyimini artırmayı ve daha tutarlı bir veri akışı sağlamayı hedefliyor.
141 lines
5.6 KiB
TypeScript
141 lines
5.6 KiB
TypeScript
import { Suspense } from "react";
|
||
import type { Metadata } from "next";
|
||
import { cookies } from "next/headers";
|
||
import { PUAN_TURLERI, type PuanTuruKey } from "@/types/yokatlas";
|
||
import {
|
||
cerezdenTercihProfili,
|
||
PROFIL_CEREZ_ADI,
|
||
} from "@/features/sihirbaz/sihirbaz-sabitler";
|
||
import {
|
||
SonucProgramTablosu,
|
||
SonucProgramTablosuSkeleton,
|
||
} from "@/features/liste/components/sonuc-program-tablosu";
|
||
import { ManuelHarita } from "@/features/liste/components/manuel-harita";
|
||
import { TadimlikBolumu } from "@/features/rapor/components/tadimlik-bolumu";
|
||
import { SonucSihirbazi } from "@/features/sihirbaz/components/sihirbaz-bolumu";
|
||
import { SiraGerekli } from "@/features/sihirbaz/components/sira-gerekli";
|
||
import { SiteFooter } from "@/components/site-footer";
|
||
import { Skeleton } from "@/components/ui/skeleton";
|
||
|
||
export const metadata: Metadata = {
|
||
title: "Tercih Listeni Kur",
|
||
// İçerik profil çerezine göre kişisel (eski linklerde param uzayı sonsuz):
|
||
// indexlenmez ama link değeri follow ile geri akar. robots.txt'te
|
||
// ENGELLEME — noindex'in görülebilmesi için sayfa taranabilir kalmalı.
|
||
robots: { index: false, follow: true },
|
||
};
|
||
|
||
export default function SonucPage({
|
||
searchParams,
|
||
}: {
|
||
searchParams: Promise<{
|
||
sira?: string;
|
||
tur?: string;
|
||
sihirbaz?: string;
|
||
hazir?: string;
|
||
il?: string | string[];
|
||
tip?: string;
|
||
}>;
|
||
}) {
|
||
return (
|
||
// Tablo değişken boylu olduğundan altındaki tadımlık, sihirbaz, dipnot ve
|
||
// footer aynı sınırda gruplu — bugünkü tek await'li akışla birebir aynı
|
||
// anda beliriyorlar, ara durumda zıplama yok.
|
||
<Suspense
|
||
fallback={
|
||
<main className="mx-auto w-full max-w-6xl px-4 py-10">
|
||
<Skeleton className="h-6 w-40 rounded-full" />
|
||
<Skeleton className="mt-4 h-9 w-3/4 max-w-xl" />
|
||
<Skeleton className="mt-3 h-5 w-2/3 max-w-lg" />
|
||
<Skeleton className="mt-8 h-36 w-full rounded-2xl" />
|
||
<SonucProgramTablosuSkeleton />
|
||
</main>
|
||
}
|
||
>
|
||
{Promise.all([searchParams, cookies()]).then(([params, cerezler]) => {
|
||
// Profil (sıra/tür/il/tip) normalde PROFIL_CEREZ_ADI çerezinden gelir;
|
||
// URL param taşımaz (bkz. sonucHref). Query'de sira varsa eski
|
||
// paylaşılan/yer imli link demektir — açık URL niyeti çerezi ezer,
|
||
// eski linkler çalışmayı sürdürür.
|
||
const eskiLinkSira = Number.parseInt(params.sira ?? "", 10);
|
||
const eskiLink = Number.isFinite(eskiLinkSira);
|
||
const profil = eskiLink
|
||
? null
|
||
: cerezdenTercihProfili(cerezler.get(PROFIL_CEREZ_ADI)?.value);
|
||
|
||
const sira = eskiLink ? eskiLinkSira : (profil?.sira ?? Number.NaN);
|
||
const turHam = eskiLink ? params.tur : profil?.tur;
|
||
const turKey: PuanTuruKey =
|
||
turHam && turHam in PUAN_TURLERI ? (turHam as PuanTuruKey) : "say";
|
||
// Tablo filtreleri: il en fazla 5 tekrarsız, tip devlet|vakif
|
||
// allowlist'li (çerez tarafı tercihProfiliDogrula'dan zaten geçmiş
|
||
// olsa da iki kaynak aynı süzgeçten akar).
|
||
const hamIller = eskiLink
|
||
? Array.isArray(params.il)
|
||
? params.il
|
||
: params.il
|
||
? [params.il]
|
||
: []
|
||
: (profil?.secimler.iller ?? []);
|
||
const iller = [
|
||
...new Set(hamIller.filter((i) => i.trim().length > 0)),
|
||
].slice(0, 5);
|
||
const tipHam = eskiLink ? params.tip : profil?.secimler.universiteTipi;
|
||
const uniturGrubu =
|
||
tipHam === "devlet" || tipHam === "vakif" ? tipHam : undefined;
|
||
|
||
if (!Number.isFinite(sira) || sira < 1 || sira > 4_000_000) {
|
||
return (
|
||
<>
|
||
<SiraGerekli />
|
||
<SiteFooter />
|
||
</>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div className="min-h-screen bg-slate-50 text-slate-900">
|
||
<main className="mx-auto max-w-4xl px-4 py-12">
|
||
{/* Sayfa hiyerarşisi: önce Türkiye haritası, sonra liste. Manuel
|
||
liste store'una abone olduğundan tablodan "+" ile eklenenler
|
||
buraya canlı yansır. */}
|
||
<ManuelHarita />
|
||
|
||
{/* Yapay Zeka'dan bağımsız ham tablo — haritanın hemen altında,
|
||
sayfanın ana gövdesi; puan türü navbar'daki sıralama
|
||
rozetinden değiştirilir. Sihirbaz seçimleri (il, devlet/
|
||
vakıf) profil çerezinden tabloya uygulanır. */}
|
||
<SonucProgramTablosu
|
||
sira={sira}
|
||
tur={turKey}
|
||
iller={iller}
|
||
uniturGrubu={uniturGrubu}
|
||
/>
|
||
|
||
{/* Girişsiz tadımlık: gerçek rapor satırı formatında tek örnek.
|
||
Havuzda içerik yoksa bileşen hiç render edilmez. */}
|
||
<TadimlikBolumu sira={sira} tur={turKey} />
|
||
|
||
{/* Sihirbaz akışı (CTA + modal) — üretim ve liste /listem'de
|
||
yaşar, burada yalnızca funnel kartları render edilir */}
|
||
<SonucSihirbazi
|
||
sira={sira}
|
||
tur={turKey}
|
||
otomatikAc={params.sihirbaz === "1"}
|
||
secimlerHazir={params.hazir === "1"}
|
||
/>
|
||
|
||
<p className="mt-10 text-center text-xs leading-relaxed text-slate-500">
|
||
Veriler resmî YÖK Atlas kaynağından derlenmiştir. KolayTercih
|
||
bir karar destek aracıdır; yerleşme garantisi vermez, tercih
|
||
sorumluluğu adaya aittir.
|
||
</p>
|
||
</main>
|
||
<SiteFooter />
|
||
</div>
|
||
);
|
||
})}
|
||
</Suspense>
|
||
);
|
||
}
|