/** * Rybbit analitiği için ince sarmalayıcı. * * Script yalnızca prod build'de yükleniyor (bkz. app/layout.tsx) ve reklam * engelleyiciler tarafından bloklanabiliyor; bu yüzden buradaki her çağrı * `window.rybbit` yoksa sessizce hiçbir şey yapmaz — çağıran taraf asla * varlık kontrolü yapmak zorunda kalmasın. * * KURAL: Öğrencinin ham başarı sıralaması analitiğe GÖNDERİLMEZ. Sıralama * her zaman `siraKovasi()` ile bantlanır. */ /** Ölçtüğümüz huni olayları. Yeni olay eklerken bu birliği genişlet. */ export type OlayAdi = | "sira_girildi" | "sihirbaz_adim" | "sihirbaz_tamamlandi" | "giris_denendi" | "liste_olusturuldu" | "liste_revize" | "program_eklendi" | "netler_goruntulendi" | "danisman_sorusu" | "katalog_arama" | "odeme_baslatildi" | "hazir_panel_goruntulendi" | "giris_cta_tiklandi" | "kilit_goruntulendi" | "kredi_bitti" | "tadimlik_goruntulendi" | "kaydet_banner_goruntulendi"; export type Ozellikler = Record; interface RybbitApi { event: (ad: string, ozellikler?: Ozellikler) => void; pageview: () => void; identify: (kullaniciId: string, traits?: Record) => void; setTraits: (traits: Record) => void; clearUserId: () => void; getUserId: () => string | null; } declare global { interface Window { rybbit?: RybbitApi; } } /** Özel olay gönderir. Script yoksa no-op. */ export function olay(ad: OlayAdi, ozellikler?: Ozellikler): void { if (typeof window === "undefined") return; try { window.rybbit?.event(ad, ozellikler); } catch { // Analitik hiçbir koşulda kullanıcı akışını bozmaz } } /** * Ham sıralamayı analitik için bantlar. Panelde "hangi sıralama bandı * dönüşüyor" sorusunu yanıtlar ama tekil öğrenciyi işaret etmez. */ export function siraKovasi(sira: number): string { if (sira <= 10_000) return "0-10 bin"; if (sira <= 50_000) return "10-50 bin"; if (sira <= 100_000) return "50-100 bin"; if (sira <= 250_000) return "100-250 bin"; if (sira <= 500_000) return "250-500 bin"; return "500 bin+"; } /** * Giriş yapan kullanıcıyı eşler. İlk çağrıda o cihazdaki önceki anonim * olaylar geriye dönük olarak bu kullanıcıya bağlanır (sihirbazı doldurup * sonra giriş yapan öğrencinin yolculuğu tek profilde birleşsin diye). */ export function kullaniciTanit( kullaniciId: string, traits?: Record, ): void { if (typeof window === "undefined") return; try { window.rybbit?.identify(kullaniciId, traits); } catch { // yut } } /** Çıkışta kimliği temizler. */ export function kullaniciTemizle(): void { if (typeof window === "undefined") return; try { window.rybbit?.clearUserId(); } catch { // yut } }