diff --git a/src/features/liste/components/program-ekle-butonu.tsx b/src/features/liste/components/program-ekle-butonu.tsx
index 46a077e..95613cc 100644
--- a/src/features/liste/components/program-ekle-butonu.tsx
+++ b/src/features/liste/components/program-ekle-butonu.tsx
@@ -1,6 +1,6 @@
"use client";
-import { Check, Plus } from "lucide-react";
+import { ArrowRight, Check, Plus } from "lucide-react";
import { toast } from "sonner";
import type { Program } from "@/types/yokatlas";
import { olay } from "@/lib/analitik";
@@ -10,7 +10,10 @@ import {
useListedeMi,
type ManuelKaynak,
} from "../liste-store";
-import { programEkleIste } from "../hooks/use-tercih-profili";
+import {
+ profilToplamaAc,
+ programEkleIste,
+} from "../hooks/use-tercih-profili";
import { preloadTercihProfiliKapisi } from "./tercih-profili-kapisi-lazy";
type ProgramOzet = Pick<
@@ -25,6 +28,8 @@ type ProgramOzet = Pick<
| "sira2024"
>;
+const PROFILSIZ_EKLEME_TOAST_ID = "profilsiz-ekleme";
+
export function ProgramEkleButonu({
program,
kaynak = "sonuc",
@@ -52,8 +57,33 @@ export function ProgramEkleButonu({
toast.info(`Listen ${MANUEL_LISTE_MAX} tercihe ulaştı.`);
} else if (sonuc.zatenVar) {
toast.info("Bu program zaten seçtiklerinde.");
- } else {
- olay("program_eklendi", { kaynak });
+ } else if (sonuc.eklendi) {
+ olay("program_eklendi", {
+ kaynak,
+ yol: "dogrudan",
+ profilli: sonuc.profilsiz ? "hayir" : "evet",
+ });
+ if (sonuc.profilsiz) {
+ // Önce ver, sonra iste: program eklendi; sıralama sorusu değer
+ // karşılığında gelir. Sabit id → art arda +'larda toast yığılmaz,
+ // aynı toast tazelenir.
+ toast.success("Seçtiklerine eklendi", {
+ id: PROFILSIZ_EKLEME_TOAST_ID,
+ duration: 8000,
+ description:
+ "Sıralamanı girersen bu programın risk seviyesini de gösteririz.",
+ action: {
+ label: (
+
+ Sıralamamı gir
+
+
+ ),
+ // Tanıtım ekranını atla, doğrudan sıralama adımı
+ onClick: () => profilToplamaAc(null, true, "arti_toast"),
+ },
+ });
+ }
}
}
@@ -62,7 +92,8 @@ export function ProgramEkleButonu({
type="button"
disabled={listede || doldu}
onClick={handleClick}
- // Profilsiz kullanıcıda + kapıyı açar — chunk'ı niyet anında ısıt
+ // Profilsiz eklemenin toast aksiyonu kapıyı açar — chunk'ı niyet
+ // anında ısıt
onPointerEnter={preloadTercihProfiliKapisi}
onFocus={preloadTercihProfiliKapisi}
title={
diff --git a/src/features/liste/components/tercih-profili-kapisi.tsx b/src/features/liste/components/tercih-profili-kapisi.tsx
index 7085430..7ab9ce9 100644
--- a/src/features/liste/components/tercih-profili-kapisi.tsx
+++ b/src/features/liste/components/tercih-profili-kapisi.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { ArrowRight, Trophy } from "lucide-react";
import { useReducedMotion } from "motion/react";
@@ -53,17 +53,38 @@ type Adim = "giris" | "sira" | "sihirbaz";
const ADIM_SIRASI: Record = { giris: 0, sira: 1, sihirbaz: 2 };
export function TercihProfiliKapisi() {
- const { acik, duzenle, dogrudanSira, bekleyen, bekleyenHedef, profil } =
- useProfilKapisi();
+ const {
+ acik,
+ duzenle,
+ dogrudanSira,
+ tetik,
+ bekleyen,
+ bekleyenHedef,
+ profil,
+ } = useProfilKapisi();
+ // Kapanış olayı için o an görünen adım; KapıIcerik her adım değişiminde
+ // (ve mount'ta) bildirir. Render'ı etkilemediği için state değil ref.
+ const adimRef = useRef("giris");
const oturumAnahtari = acik
? `${duzenle ? "d" : "n"}-${bekleyen?.program.id ?? "yok"}-${profil?.sira ?? 0}-${profil?.tur ?? ""}`
: "kapali";
+ // Tamamlanmadan kapanışın TEK noktası: X, dışarı tıklama, Esc (Dialog
+ // onOpenChange) ve içerideki "Vazgeç" butonları buradan geçer.
+ // Tamamlanan kapı buraya uğramaz: secimleriTamamla → profilTamamlandi
+ // depoda `acik`'ı doğrudan kapatır; Radix kontrollü `open` prop'u
+ // değişince onOpenChange çağırmaz → `kapi_kapatildi` atılmaz.
+ function vazgec() {
+ if (!acik) return;
+ olay("kapi_kapatildi", { adim: adimRef.current, tetik });
+ profilKapisiniKapat();
+ }
+
return (