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.
91 lines
3.1 KiB
TypeScript
91 lines
3.1 KiB
TypeScript
// Ortak tercih profilinin localStorage katmanı — yalnızca client'ta anlamlı.
|
||
// Şema, doğrulama ve sabitler sihirbaz-sabitler.ts'te yaşar.
|
||
|
||
import {
|
||
PROFIL_CEREZ_ADI,
|
||
PROFIL_DEGISTI_EVENT,
|
||
SIHIRBAZ_STORAGE_KEY,
|
||
tercihProfiliDogrula,
|
||
type TercihProfili,
|
||
} from "./sihirbaz-sabitler";
|
||
|
||
function profilDegistiginiYayinla(): void {
|
||
window.dispatchEvent(new Event(PROFIL_DEGISTI_EVENT));
|
||
}
|
||
|
||
// tercihProfiliOku 18 farklı yerden çağrılıyor ve tek bir "+" tıklaması bile
|
||
// 3 kez okuyabiliyor; her çağrıda localStorage + JSON.parse + şema doğrulama
|
||
// yapmamak için modül seviyesi cache (js-cache-storage). Geçersizleme iki
|
||
// kanaldan: aynı sekmede PROFIL_DEGISTI_EVENT, diğer sekmelerde "storage".
|
||
// undefined = henüz okunmadı, null = okundu ve profil yok.
|
||
let profilCache: TercihProfili | null | undefined;
|
||
if (typeof window !== "undefined") {
|
||
window.addEventListener(PROFIL_DEGISTI_EVENT, () => {
|
||
profilCache = undefined;
|
||
});
|
||
window.addEventListener("storage", (e) => {
|
||
if (e.key === SIHIRBAZ_STORAGE_KEY || e.key === null) {
|
||
profilCache = undefined;
|
||
}
|
||
});
|
||
}
|
||
|
||
/** Client'ta SIHIRBAZ_STORAGE_KEY'den doğrulanmış profil okur. */
|
||
export function tercihProfiliOku(): TercihProfili | null {
|
||
if (typeof window === "undefined") return null;
|
||
if (profilCache !== undefined) return profilCache;
|
||
try {
|
||
const ham = localStorage.getItem(SIHIRBAZ_STORAGE_KEY);
|
||
profilCache = ham ? tercihProfiliDogrula(JSON.parse(ham)) : null;
|
||
} catch {
|
||
profilCache = null;
|
||
}
|
||
return profilCache;
|
||
}
|
||
|
||
/**
|
||
* Profilin sunucu aynası: /sonuc SSR'ı tabloyu bu çerezden filtreler
|
||
* (bkz. PROFIL_CEREZ_ADI). localStorage'ı olup çerezi olmayan eski
|
||
* kullanıcıların taşınması için SiraGerekli de bunu çağırır.
|
||
*/
|
||
export function profilCerezineYaz(profil: TercihProfili): void {
|
||
if (typeof document === "undefined") return;
|
||
const guvenli = window.location.protocol === "https:" ? "; secure" : "";
|
||
document.cookie = `${PROFIL_CEREZ_ADI}=${encodeURIComponent(
|
||
JSON.stringify(profil),
|
||
)}; path=/; max-age=31536000; samesite=lax${guvenli}`;
|
||
}
|
||
|
||
function profilCereziniSil(): void {
|
||
if (typeof document === "undefined") return;
|
||
document.cookie = `${PROFIL_CEREZ_ADI}=; path=/; max-age=0`;
|
||
}
|
||
|
||
/** Ortak profili yazar; hero ve Yapay Zeka sihirbazıyla aynı anahtarı kullanır. */
|
||
export function tercihProfiliYaz(profil: TercihProfili): void {
|
||
if (typeof window === "undefined") return;
|
||
const dogru = tercihProfiliDogrula(profil);
|
||
if (!dogru) return;
|
||
try {
|
||
localStorage.setItem(SIHIRBAZ_STORAGE_KEY, JSON.stringify(dogru));
|
||
} catch {}
|
||
profilCerezineYaz(dogru);
|
||
profilCache = dogru;
|
||
profilDegistiginiYayinla();
|
||
}
|
||
|
||
/** Profili siler (ör. Yapay Zeka listesi üretilip seçimler tüketildiğinde). */
|
||
export function tercihProfiliSil(): void {
|
||
if (typeof window === "undefined") return;
|
||
try {
|
||
localStorage.removeItem(SIHIRBAZ_STORAGE_KEY);
|
||
} catch {}
|
||
profilCereziniSil();
|
||
profilCache = null;
|
||
profilDegistiginiYayinla();
|
||
}
|
||
|
||
export function tercihProfiliTamamlandiMi(): boolean {
|
||
return tercihProfiliOku() !== null;
|
||
}
|