feat(olcum): sihirbazın 1. adımı ve kaynaksız /paket linkleri ölçülür
(a) `sihirbaz_adim{adim:1}` artık sihirbaz modalı açıldığında atılıyor.
Bugüne kadar olay yalnız `adimaGit`in ileri geçişinde atılıyordu; modal
zaten 1. adımda açıldığı için 1. adım hiç "geçilmiyor", dolayısıyla hiç
sayılmıyordu ve huninin paydası `sira_girildi`den türetilmek zorunda
kalıyordu. Mount effect'i + `olayBirKez` ile tam bir kez düşüyor:
1→2→1→2 gezinmesi bileşeni unmount etmediği için tekrar tetiklemiyor,
sessionStorage tekilleştirmesi de aynı sekmede ikinci açılışı sayıyor.
SERİ KIRILMASI: bu değişikliğin canlıya çıktığı tarihten ÖNCEKİ
`sihirbaz_adim` serisinin paydası farklıdır — o dönemde `adim:1` hiç
atılmadı, seri yalnız 2 ve 3'ten oluşuyor. Öncesi ve sonrası
karşılaştırılamaz; huni okumalarında kırılma tarihi dipnot edilmeli.
Aynı desen `program_eklendi` için 21 Eylül'de uygulanmıştı.
(b) Kaynaksız 10 `/paket` linkine tekil `?kaynak=` eklendi; sitedeki 14
`/paket` linkinin 14'ünde artık kaynak var. Değerler mevcut şemayla
(`kilit`, `kredi_bitti`, `nav`) aynı dilde: fiyat_paket, fiyat_kredi,
kosullar, tercih_degisti, tercih_degisti_yetersiz, danisman_rozet,
danisman_kredi_bitti, danisman_kredi_az, odeme_geri, odeme_hata.
`paket-gorunum-olayi.tsx`'teki `KAYNAKLAR` allowlist'i de genişletildi:
listede olmayan her değer `"diger"`e düştüğü için, genişletilmeseydi 10
yeni kaynağın tamamı tek kovada toplanır ve ölçüm deliği kapanmazdı
(bağımlılık kapanışı — dosya şartnamenin listesinde yoktu, raporda
sapma olarak yazıldı).
Görsel değişiklik yok; yeni olay adı ya da yeni ölçüm yüzeyi eklenmedi.
Doğrulama: `next typegen` + `tsc --noEmit` + `lint` temiz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
72
docs/gece-vardiyasi/2026-09-22/08-p4-olcum.md
Normal file
72
docs/gece-vardiyasi/2026-09-22/08-p4-olcum.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# P4 — İki ölçüm deliği · `gece/0922-olcum`
|
||||||
|
|
||||||
|
**Tur 3 · yazılımcı raporu · 2026-09-23**
|
||||||
|
|
||||||
|
## Özet (5 madde)
|
||||||
|
|
||||||
|
1. `sihirbaz_adim{adim:1}` artık sihirbaz modalı açıldığında (bileşenin mount'unda) bir kez atılıyor; huninin paydası `sira_girildi`den türetilmek zorunda değil.
|
||||||
|
2. Tekrar sayma koruması iki katmanlı: bileşen 1↔2 gezinmesinde unmount olmuyor (mount effect tekrar koşmuyor) **ve** `olayBirKez` oturum başına tekilleştiriyor.
|
||||||
|
3. Kaynaksız 10 `/paket` linkinin hepsine tekil `?kaynak=` eklendi; sitedeki 14 `/paket` linkinin 14'ünde artık kaynak var.
|
||||||
|
4. **Şartname dışı zorunlu dosya:** `paket-gorunum-olayi.tsx`'teki `KAYNAKLAR` allowlist'i genişletildi — genişletilmeseydi 10 yeni değerin tamamı Rybbit'e `"diger"` olarak düşerdi, yani iş ölçüm açısından işlevsiz kalırdı.
|
||||||
|
5. Görsel değişiklik yok: tüm diff ya yorum, ya `href` query string'i, ya da görünmez bir `useEffect`. `tsc --noEmit` ve `lint` temiz.
|
||||||
|
|
||||||
|
## Değişen dosyalar
|
||||||
|
|
||||||
|
| Dosya | Ne |
|
||||||
|
|---|---|
|
||||||
|
| `src/features/sihirbaz/components/sihirbaz-adimlar.tsx` | Mount'ta `olayBirKez("sihirbaz_adim", { adim: 1 }, "adim1")`; `adimaGit` yorumu güncellendi (adım 1 artık oradan geçmiyor) |
|
||||||
|
| `src/app/page.tsx` | 2 link |
|
||||||
|
| `src/app/kosullar/page.tsx` | 1 link |
|
||||||
|
| `src/features/rapor/components/tercih-degisti-modali.tsx` | 2 link |
|
||||||
|
| `src/features/rapor/components/sohbet-client.tsx` | 3 link |
|
||||||
|
| `src/features/odeme/components/odeme-kromu.tsx` | 1 link |
|
||||||
|
| `src/features/odeme/components/odeme-sonuc-karti.tsx` | 1 link |
|
||||||
|
| `src/features/odeme/components/paket-gorunum-olayi.tsx` | **(şartname dışı)** `KAYNAKLAR` allowlist'i 3 → 13 değer |
|
||||||
|
|
||||||
|
## Link → kaynak adı tablosu
|
||||||
|
|
||||||
|
| # | Dosya:satır | Yüzey (kullanıcı ne görüyor) | `?kaynak=` |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | `src/app/page.tsx:543` | Ana sayfa fiyat bölümü, paket kartının CTA'sı ("… TL — Paketi incele") | `fiyat_paket` |
|
||||||
|
| 2 | `src/app/page.tsx:573` | Ana sayfa fiyat bölümü, "Kredi bitti mi?" topup kartı | `fiyat_kredi` |
|
||||||
|
| 3 | `src/app/kosullar/page.tsx:55` | Koşullar · Ücretlendirme paragrafındaki "paket sayfasında" linki | `kosullar` |
|
||||||
|
| 4 | `tercih-degisti-modali.tsx:283` | "Tercihlerin değişmiş" modalı, aksiyon satırı (kredi baştan yetmiyor) | `tercih_degisti` |
|
||||||
|
| 5 | `tercih-degisti-modali.tsx:335` | Aynı modal, `durum.ad === "kredi-yetersiz"` satırı (güncelleme denendi, kredi yetmedi) | `tercih_degisti_yetersiz` |
|
||||||
|
| 6 | `sohbet-client.tsx:351` | Danışman başlığındaki "N kredi" rozeti | `danisman_rozet` |
|
||||||
|
| 7 | `sohbet-client.tsx:538` | Danışman, kredi bitti bandındaki "Kredi yükle" butonu | `danisman_kredi_bitti` |
|
||||||
|
| 8 | `sohbet-client.tsx:546` | Danışman, "son N kredin" uyarısındaki "kredi yükleyip" linki | `danisman_kredi_az` |
|
||||||
|
| 9 | `odeme-kromu.tsx:45` | `/odeme` üst şeridi, "Paket sayfasına dön" | `odeme_geri` |
|
||||||
|
| 10 | `odeme-sonuc-karti.tsx:141` | Ödeme başarısız kartı, "Tekrar dene" | `odeme_hata` |
|
||||||
|
|
||||||
|
Adlandırma dili mevcut şemadan alındı (`kilit`, `kredi_bitti`, `nav`): küçük harf, `snake_case`, yüzeyi/tetiği söyleyen kısa ad. Yeni kavram icat edilmedi; `fiyat_*` ve `danisman_*` önekleri aynı bölümdeki iki linki ayırmak için.
|
||||||
|
|
||||||
|
## Kabul kriterleri
|
||||||
|
|
||||||
|
| # | Kriter | Durum | Nasıl doğrulandı |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | Sihirbaz açılışında `sihirbaz_adim{adim:1}` tam bir kez düşer; 1→2→1→2'de tekrar düşmez | ✔ (koddan çıkarım) | Modal `Dialog`/`DialogContent` içinde, `forceMount` yok → kapanınca `SihirbazAdimlar` unmount oluyor; `adim` bileşenin iç state'i, adım değişimi unmount etmiyor → boş bağımlılıklı `useEffect` bir kez koşuyor. Ek olarak `olayBirKez` sessionStorage anahtarıyla (`kolaytercih.olay.sihirbaz_adim.adim1`) oturum başına tekilleştiriyor; bu aynı zamanda dev StrictMode'un çift effect'ini ve `hero-form`daki `key={sira-tur}` remount'unu da kapatıyor. **Tarayıcıda çalıştırılarak doğrulanmadı** (vardiya kuralı: dev sunucusu/tarayıcı yok). |
|
||||||
|
| 2 | 14 `/paket` linkinin 14'ünde `?kaynak=` var ve değerler tekil | ✔ | `grep -rn 'href="/paket' src \| grep -v 'kaynak='` → boş. 10 yeni değerin hepsi birbirinden ve mevcut 3 değerden farklı. **Uyarı:** `listem-govde.tsx:288` ve `:369` ikisi de eskiden beri `kaynak=kilit` (iki ayrı kilit yüzeyi, tek değer) — bu benim paketimde değil, aşağıda not olarak duruyor. |
|
||||||
|
| 3 | Hiçbir görsel değişiklik yok | ✔ | `git diff`: dokunulan satırlar yalnız yorum, `href` string'i ve `null` döndürmeyen hiçbir JSX eklemeyen bir `useEffect`. Hiçbir `className`, metin, ikon, düzen değişmedi. |
|
||||||
|
| 4 | Commit mesajında seri kırılması notu | ✔ | Commit gövdesinde; ayrıca `sihirbaz-adimlar.tsx` içindeki yorumda da duruyor (analist koda bakınca da görsün). |
|
||||||
|
| 5 | `tsc --noEmit` + `lint` temiz | ✔ | `pnpm exec next typegen && pnpm exec tsc --noEmit` → çıktı yok; `pnpm lint` → çıktı yok. `pnpm build` iş tanımında istenmediği için koşulmadı. |
|
||||||
|
|
||||||
|
## Şartnameden sapmalar
|
||||||
|
|
||||||
|
**1 sapma — `src/features/odeme/components/paket-gorunum-olayi.tsx` (şartnamedeki dosya listesinde yok).**
|
||||||
|
|
||||||
|
`/paket` görüntülenmesini ölçen bileşen `?kaynak=` değerini bir allowlist'ten süzüyor; listede olmayan her değer `"diger"`e düşüyor (serbest metnin analitiğe sızmaması için, doğru bir koruma). Allowlist bugün `["kilit", "kredi_bitti", "nav"]` idi. Genişletilmeseydi eklediğim 10 kaynağın **onu da** panelde tek bir `"diger"` kovasında toplanacaktı — yani iş görünüşte biter, ölçüm deliği kapanmazdı. Bağımlılık kapanışı gereği aynı commit'e alındı. Dosya P1/P2/P3 paketlerinin kapsamında değil (CEO §3 kontrol edildi), bu yüzden çakışma beklemiyorum.
|
||||||
|
|
||||||
|
Başka sapma yok. Yeni olay adı eklenmedi (`OlayAdi` birliğine dokunulmadı), yeni ölçüm yüzeyi eklenmedi, rehber sayfalarına ölçüm eklenmedi.
|
||||||
|
|
||||||
|
## Merge sonrası doğrulanması gerekenler
|
||||||
|
|
||||||
|
1. **Canlıda bir kez elle dene:** sihirbazı aç → Rybbit'te `sihirbaz_adim{adim:1}` düşüyor mu; 2. adıma geç, geri dön, tekrar ilerle → `adim:1` ikinci kez düşmemeli. (Lokal dev'de Rybbit script'i yüklenmiyor, bu yüzden burada doğrulanamadı.)
|
||||||
|
2. **Seri kırılması tarihi:** `analitik` ajanı bu değişikliğin **canlıya çıktığı** tarihi sabit dipnot yapsın (CEO §6'daki istek). Merge tarihi değil, deploy tarihi.
|
||||||
|
3. **`?kaynak=` değerleri panelde göründü mü:** `paket_goruntulendi` olayında `"diger"` kovası bir süre sonra da kalabalıksa allowlist'te unutulmuş bir yüzey var demektir.
|
||||||
|
4. `/paket` statik bir sayfa; query string eklenmesi ISR/önbellek davranışını değiştirmiyor (`?kaynak=nav` ve `?hata=token` zaten vardı), ama yayın sonrası ilk `/paket?kaynak=fiyat_paket` isteğinde 200 dönüyor mu diye bakılabilir.
|
||||||
|
|
||||||
|
## Bilal'den istenen
|
||||||
|
|
||||||
|
1. **Dalı incele ve merge et** — `gece/0922-olcum`, 1 commit, 8 dosya, tamamı görünmez ölçüm; ~5 dk.
|
||||||
|
2. **`paket-gorunum-olayi.tsx` sapmasını onayla** — şartnamede adı geçmiyordu ama onsuz iş işlevsiz kalıyordu; kabul edilmezse o dosyayı geri alıp 10 kaynağın "diger"e düşmesini kabul etmek gerekir; ~2 dk.
|
||||||
|
3. **Deploy tarihini not et** — `sihirbaz_adim` serisinin kıyaslanamaz hale geldiği gün; ~1 dk.
|
||||||
@@ -52,7 +52,7 @@ export default function KosullarPage() {
|
|||||||
Temel program arama ücretsizdir. Tercih Dönemi Paketi tek seferlik
|
Temel program arama ücretsizdir. Tercih Dönemi Paketi tek seferlik
|
||||||
bir satın almadır; abonelik değildir, otomatik yenilenmez. Paket
|
bir satın almadır; abonelik değildir, otomatik yenilenmez. Paket
|
||||||
içeriği ve güncel fiyat{" "}
|
içeriği ve güncel fiyat{" "}
|
||||||
<Link href="/paket" className="text-primary underline">
|
<Link href="/paket?kaynak=kosullar" className="text-primary underline">
|
||||||
paket sayfasında
|
paket sayfasında
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
yazar.
|
yazar.
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ export default function Home() {
|
|||||||
asChild
|
asChild
|
||||||
className="h-12 w-full cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
className="h-12 w-full cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||||
>
|
>
|
||||||
<Link href="/paket">
|
<Link href="/paket?kaynak=fiyat_paket">
|
||||||
{PAKET_FIYATI} TL — Paketi incele
|
{PAKET_FIYATI} TL — Paketi incele
|
||||||
<ArrowRight className="size-4" aria-hidden />
|
<ArrowRight className="size-4" aria-hidden />
|
||||||
</Link>
|
</Link>
|
||||||
@@ -570,7 +570,7 @@ export default function Home() {
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
className="mt-4 h-11 w-full cursor-pointer"
|
className="mt-4 h-11 w-full cursor-pointer"
|
||||||
>
|
>
|
||||||
<Link href="/paket">
|
<Link href="/paket?kaynak=fiyat_kredi">
|
||||||
+{URUNLER.topup.credits} kredi — {TOPUP_FIYATI} TL
|
+{URUNLER.topup.credits} kredi — {TOPUP_FIYATI} TL
|
||||||
<ArrowRight className="size-4" aria-hidden />
|
<ArrowRight className="size-4" aria-hidden />
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export function OdemeUstSerit() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<Link
|
<Link
|
||||||
href="/paket"
|
href="/paket?kaynak=odeme_geri"
|
||||||
className="inline-flex shrink-0 items-center gap-1.5 text-sm text-slate-500 transition-colors hover:text-slate-700"
|
className="inline-flex shrink-0 items-center gap-1.5 text-sm text-slate-500 transition-colors hover:text-slate-700"
|
||||||
>
|
>
|
||||||
<ArrowLeft className="size-4" aria-hidden />
|
<ArrowLeft className="size-4" aria-hidden />
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export async function OdemeSonucKarti({ siparis }: { siparis?: string }) {
|
|||||||
</p>
|
</p>
|
||||||
<PagePixelDivider seed={83} className="mx-auto mt-5" />
|
<PagePixelDivider seed={83} className="mx-auto mt-5" />
|
||||||
<Button asChild variant="outline" className="mt-6 h-11 cursor-pointer">
|
<Button asChild variant="outline" className="mt-6 h-11 cursor-pointer">
|
||||||
<Link href="/paket">Tekrar dene</Link>
|
<Link href="/paket?kaynak=odeme_hata">Tekrar dene</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,32 @@ import { useEffect } from "react";
|
|||||||
import { olayBirKez } from "@/lib/analitik";
|
import { olayBirKez } from "@/lib/analitik";
|
||||||
|
|
||||||
// Serbest metin analitiğe sızmasın: bilinmeyen değerler "diger"e düşer.
|
// Serbest metin analitiğe sızmasın: bilinmeyen değerler "diger"e düşer.
|
||||||
const KAYNAKLAR = ["kilit", "kredi_bitti", "nav"] as const;
|
// Yeni bir /paket linki eklerken değerini önce buraya yaz, sonra href'e koy —
|
||||||
|
// listede olmayan her kaynak "diger"e düşer ve yüzey görünmez kalır.
|
||||||
|
const KAYNAKLAR = [
|
||||||
|
// Kilitli liste satırı / kilit kartı (`listem-govde`)
|
||||||
|
"kilit",
|
||||||
|
// Üretimde kredi yetmedi (`liste-uretici`)
|
||||||
|
"kredi_bitti",
|
||||||
|
// Üst menü (`user-nav`)
|
||||||
|
"nav",
|
||||||
|
// Ana sayfa fiyat bölümü: paket kartı ve kredi (topup) kartı
|
||||||
|
"fiyat_paket",
|
||||||
|
"fiyat_kredi",
|
||||||
|
// Koşullar metnindeki "paket sayfasında" linki
|
||||||
|
"kosullar",
|
||||||
|
// "Tercihlerin değişmiş" modalı: aksiyon satırı / kredi-yetersiz satırı
|
||||||
|
"tercih_degisti",
|
||||||
|
"tercih_degisti_yetersiz",
|
||||||
|
// Danışman sohbeti: başlıktaki kredi rozeti, kredi bitti bandı, son krediler
|
||||||
|
// uyarısı
|
||||||
|
"danisman_rozet",
|
||||||
|
"danisman_kredi_bitti",
|
||||||
|
"danisman_kredi_az",
|
||||||
|
// Ödeme akışı: checkout şeridindeki geri linki, başarısız sonuç kartı
|
||||||
|
"odeme_geri",
|
||||||
|
"odeme_hata",
|
||||||
|
] as const;
|
||||||
|
|
||||||
export function PaketGorunumOlayi() {
|
export function PaketGorunumOlayi() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ export function SohbetClient({
|
|||||||
</button>
|
</button>
|
||||||
) : null}
|
) : null}
|
||||||
<Link
|
<Link
|
||||||
href="/paket"
|
href="/paket?kaynak=danisman_rozet"
|
||||||
className="inline-flex items-center gap-1.5 rounded-full border border-amber-200 bg-amber-50 px-2.5 py-1 text-xs font-semibold text-amber-700 transition-colors hover:bg-amber-100"
|
className="inline-flex items-center gap-1.5 rounded-full border border-amber-200 bg-amber-50 px-2.5 py-1 text-xs font-semibold text-amber-700 transition-colors hover:bg-amber-100"
|
||||||
title="Kredilerin — yüklemek için tıkla"
|
title="Kredilerin — yüklemek için tıkla"
|
||||||
>
|
>
|
||||||
@@ -535,7 +535,7 @@ export function SohbetClient({
|
|||||||
size="sm"
|
size="sm"
|
||||||
className="cursor-pointer bg-orange-500 text-white hover:bg-orange-600"
|
className="cursor-pointer bg-orange-500 text-white hover:bg-orange-600"
|
||||||
>
|
>
|
||||||
<Link href="/paket">Kredi yükle</Link>
|
<Link href="/paket?kaynak=danisman_kredi_bitti">Kredi yükle</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -543,7 +543,7 @@ export function SohbetClient({
|
|||||||
{kredi <= 3 ? (
|
{kredi <= 3 ? (
|
||||||
<p className="mb-2 px-1 text-xs text-amber-700">
|
<p className="mb-2 px-1 text-xs text-amber-700">
|
||||||
Son {kredi} kredin — bitse de listen ve sohbetin kaybolmaz;{" "}
|
Son {kredi} kredin — bitse de listen ve sohbetin kaybolmaz;{" "}
|
||||||
<Link href="/paket" className="underline hover:text-amber-800">
|
<Link href="/paket?kaynak=danisman_kredi_az" className="underline hover:text-amber-800">
|
||||||
kredi yükleyip
|
kredi yükleyip
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
kaldığın yerden devam edersin.
|
kaldığın yerden devam edersin.
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ export function TercihDegistiModali({
|
|||||||
asChild
|
asChild
|
||||||
className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
|
className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
|
||||||
>
|
>
|
||||||
<Link href="/paket">
|
<Link href="/paket?kaynak=tercih_degisti">
|
||||||
{hasPaket
|
{hasPaket
|
||||||
? "Kredi yükle ve güncelle"
|
? "Kredi yükle ve güncelle"
|
||||||
: "Paketi aktive et"}
|
: "Paketi aktive et"}
|
||||||
@@ -332,7 +332,7 @@ function KrediYetersiz({
|
|||||||
asChild
|
asChild
|
||||||
className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
|
className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
|
||||||
>
|
>
|
||||||
<Link href="/paket">
|
<Link href="/paket?kaynak=tercih_degisti_yetersiz">
|
||||||
{hasPaket ? "Kredi yükle" : "Paketi aktive et"}
|
{hasPaket ? "Kredi yükle" : "Paketi aktive et"}
|
||||||
<ArrowRight className="size-4" aria-hidden />
|
<ArrowRight className="size-4" aria-hidden />
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { IlSecimHaritasi } from "./il-secim-haritasi";
|
import { IlSecimHaritasi } from "./il-secim-haritasi";
|
||||||
import { normalizeIlAdi } from "@/lib/harita";
|
import { normalizeIlAdi } from "@/lib/harita";
|
||||||
import { onbellekliJsonGetir } from "@/lib/istek-cache";
|
import { onbellekliJsonGetir } from "@/lib/istek-cache";
|
||||||
import { olay } from "@/lib/analitik";
|
import { olay, olayBirKez } from "@/lib/analitik";
|
||||||
import { trBaslikDuzeni } from "@/lib/slug";
|
import { trBaslikDuzeni } from "@/lib/slug";
|
||||||
import type { SihirbazFacetleri } from "@/types/yokatlas";
|
import type { SihirbazFacetleri } from "@/types/yokatlas";
|
||||||
import { ONCELIKLER, UNIVERSITE_TIPI_ETIKET, type SihirbazSecimleri, type UniversiteTipi } from "@/features/sihirbaz/sihirbaz-sabitler";
|
import { ONCELIKLER, UNIVERSITE_TIPI_ETIKET, type SihirbazSecimleri, type UniversiteTipi } from "@/features/sihirbaz/sihirbaz-sabitler";
|
||||||
@@ -141,6 +141,20 @@ export function SihirbazAdimlar({
|
|||||||
() => canliFacetler.iller.filter((i) => HARITA_ILLERI.has(i.il)),
|
() => canliFacetler.iller.filter((i) => HARITA_ILLERI.has(i.il)),
|
||||||
[canliFacetler.iller],
|
[canliFacetler.iller],
|
||||||
);
|
);
|
||||||
|
// Huninin paydası: 1. adım hiçbir zaman "geçilmediği" için `adimaGit`ten
|
||||||
|
// atılamıyordu (orası yalnız ileri geçişleri sayar) ve `sihirbaz_adim{1}`
|
||||||
|
// hiç düşmüyordu — payda `sira_girildi`den türetilmek zorunda kalıyordu.
|
||||||
|
// Modal kapanınca bileşen unmount olduğu için mount = "1. adım görüldü";
|
||||||
|
// 1→2→1→2 gidip gelmek unmount etmediğinden tekrar tetiklenmez.
|
||||||
|
// `olayBirKez` oturum başına da tekilleştirir: aynı sekmede sihirbazı
|
||||||
|
// ikinci kez açmak paydayı şişirmez (bkz. lib/analitik.ts).
|
||||||
|
//
|
||||||
|
// SERİ KIRILMASI: bu satırın canlıya çıktığı tarihten önce `sihirbaz_adim`
|
||||||
|
// serisinde `adim:1` hiç yok; öncesi/sonrası karşılaştırılamaz.
|
||||||
|
useEffect(() => {
|
||||||
|
olayBirKez("sihirbaz_adim", { adim: 1 }, "adim1");
|
||||||
|
}, []);
|
||||||
|
|
||||||
const [facetYukleniyor, setFacetYukleniyor] = useState(false);
|
const [facetYukleniyor, setFacetYukleniyor] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (adim === 0) return;
|
if (adim === 0) return;
|
||||||
@@ -201,7 +215,8 @@ export function SihirbazAdimlar({
|
|||||||
setYon(yeniAdim > adim ? 1 : -1);
|
setYon(yeniAdim > adim ? 1 : -1);
|
||||||
setGecisBasladi(true);
|
setGecisBasladi(true);
|
||||||
setAdim(yeniAdim);
|
setAdim(yeniAdim);
|
||||||
// Yalnızca ileri geçişler huni adımı sayılır; geri dönüşler tekrar saymasın
|
// Yalnızca ileri geçişler huni adımı sayılır; geri dönüşler tekrar saymasın.
|
||||||
|
// `adim:1` buradan hiç geçmez — onu yukarıdaki mount effect'i atar.
|
||||||
if (yeniAdim > adim) olay("sihirbaz_adim", { adim: yeniAdim + 1 });
|
if (yeniAdim > adim) olay("sihirbaz_adim", { adim: yeniAdim + 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user