fix(liste): profilsiz + sonrası riskler her profil yolunda dolsun

P6'nın bilinen eksiği: riskleriYenile yalnız kapı tamamlanınca çağrılıyordu;
profil hero/CTA formu, sihirbaz ya da giriş senkronuyla yazılınca önceden
eklenenlerin riski null kalıyor, /sonuc haritasında yanlış renkle pinleniyordu.
Liste deposu artık açılışta ve her PROFIL_DEGISTI_EVENT'te riskleri yeniler.
Çekmece alt kartı da riski hesaplanmamış listede analizi 'hazır' diye duyurmaz.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-09-21 15:29:04 +03:00
parent 97952f6e06
commit f17ee48a88
2 changed files with 16 additions and 3 deletions

View File

@@ -91,6 +91,9 @@ export function ListeCekmecesi() {
const [oturdu, setOturdu] = useState(false); const [oturdu, setOturdu] = useState(false);
const doluluk = Math.round((liste.length / MANUEL_LISTE_MAX) * 100); const doluluk = Math.round((liste.length / MANUEL_LISTE_MAX) * 100);
// Profilsiz + ile eklenenlerin riski henüz hesaplanmamıştır; alt kart
// olmayan bir analizi "hazır" diye duyurmasın.
const riskEksik = liste.some((t) => t.risk == null);
function programaEkleGit() { function programaEkleGit() {
cekmeceKapat(); cekmeceKapat();
@@ -269,10 +272,12 @@ export function ListeCekmecesi() {
</div> </div>
<div className="min-w-0"> <div className="min-w-0">
<p className="font-heading text-2xl font-bold"> <p className="font-heading text-2xl font-bold">
Risk analizini biz yaptık {riskEksik ? "Risk analizi sıralamanı bekliyor" : "Risk analizini biz yaptık"}
</p> </p>
<p className="mt-1 truncate text-sm leading-relaxed text-white"> <p className="mt-1 truncate text-sm leading-relaxed text-white">
Her seçimin yerleşme riski hazır — son kararı sen ver. {riskEksik
? "Sıralamanı girince her seçimin riskini gösteririz."
: "Her seçimin yerleşme riski hazır — son kararı sen ver."}
</p> </p>
</div> </div>
<Button <Button

View File

@@ -8,7 +8,10 @@
import { useSyncExternalStore } from "react"; import { useSyncExternalStore } from "react";
import type { Program } from "@/types/yokatlas"; import type { Program } from "@/types/yokatlas";
import { riskHesapla } from "@/lib/risk"; import { riskHesapla } from "@/lib/risk";
import { type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler"; import {
PROFIL_DEGISTI_EVENT,
type TercihProfili,
} from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliOku } from "@/features/sihirbaz/sihirbaz-profil"; import { tercihProfiliOku } from "@/features/sihirbaz/sihirbaz-profil";
import { import {
MANUEL_LISTE_MAX, MANUEL_LISTE_MAX,
@@ -49,6 +52,11 @@ function yukle() {
const ham = localStorage.getItem(STORAGE_KEY); const ham = localStorage.getItem(STORAGE_KEY);
if (ham) liste = dogrula(JSON.parse(ham)); if (ham) liste = dogrula(JSON.parse(ham));
} catch {} } catch {}
// Profilsiz + ile eklenenlerin riski null'dır. Profil sonradan hangi yoldan
// yazılırsa yazılsın (kapı, hero/CTA formu, sihirbaz, giriş senkronu) riskler
// dolsun: açılışta bir kez, sonra her profil değişiminde.
if (liste.some((t) => t.risk == null)) riskleriYenile();
window.addEventListener(PROFIL_DEGISTI_EVENT, () => riskleriYenile());
// Başka sekmede yapılan değişiklikleri de yansıt // Başka sekmede yapılan değişiklikleri de yansıt
window.addEventListener("storage", (e) => { window.addEventListener("storage", (e) => {
if (e.key !== STORAGE_KEY) return; if (e.key !== STORAGE_KEY) return;