refactor: sihirbaz feature'ı — lib/sihirbaz bölündü, bileşenler taşındı (Faz 6)

- lib/sihirbaz.ts ikiye ayrıldı: sihirbaz-sabitler.ts (şema + doğrulayıcılar +
  event/storage sabitleri + sonucHref/secimOzeti, izomorfik) ve
  sihirbaz-profil.ts (localStorage oku/yaz/sil); 25 tüketicinin importu
  sembol bazında bölünerek güncellendi, localStorage anahtar/event değerleri
  birebir aynı
- sihirbaz-adimlar(+lazy), hero-form, cta-sira-form, il-secim-haritasi ve
  /sonuc'un sihirbaz-modal/sihirbaz-cagri-karti/sira-gerekli bileşenleri
  features/sihirbaz/components/ altına taşındı
- sihirbaz-queries.ts ve async SihirbazBolumu sarmalayıcısı /sonuc sayfa
  dönüşümüyle birlikte Faz 9'da gelecek (o zamana dek ölü kod olurlardı)
- Davranış değişikliği yok

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-08-08 01:31:32 +03:00
parent baebc1fc80
commit 792e8c7346
36 changed files with 102 additions and 128 deletions

View File

@@ -13,7 +13,7 @@ import { sohbetAkisi } from "@/lib/ai/cagri";
import { listeOzetiCikar } from "@/lib/ai/rapor";
import type { RaporSonuc } from "@/features/rapor/types/rapor";
import type { RaporParams } from "@/features/rapor/types/rapor";
import { secimOzeti } from "@/lib/sihirbaz";
import { secimOzeti } from "@/features/sihirbaz/sihirbaz-sabitler";
import { PUAN_TURLERI } from "@/types/yokatlas";
import { ACIK_SATIR } from "@/lib/rapor-maske";

View File

@@ -13,12 +13,8 @@ import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { listeOlustur } from "@/app/sonuc/actions";
import { olay, siraKovasi } from "@/lib/analitik";
import {
sonucHref,
tercihProfiliOku,
tercihProfiliSil,
type TercihProfili,
} from "@/lib/sihirbaz";
import { sonucHref, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliOku, tercihProfiliSil } from "@/features/sihirbaz/sihirbaz-profil";
const URETIM_MESAJLARI = [
"Sıralamana uygun programlar taranıyor…",

View File

@@ -5,7 +5,7 @@ import { ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { PagePixelDivider } from "@/components/pixel-decor";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
import { sonucHref } from "@/lib/sihirbaz";
import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
/**
* /listem boş hâlinin metni + CTA'sı: sıralamasını zaten girmiş adaya

View File

@@ -4,7 +4,7 @@ import Link from "next/link";
import { ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
import { sonucHref } from "@/lib/sihirbaz";
import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
/**
* Ödeme başarılı ama henüz Yapay Zeka listesi yokken gösterilen CTA: kayıtlı tercih

View File

@@ -18,7 +18,7 @@ import { Suspense } from "react";
import { ComparisonCell } from "@/features/pazarlama/components/landing-parcalari";
import { HeroBaslik } from "@/features/pazarlama/components/hero-baslik";
import { KapanisCta } from "@/features/pazarlama/components/hero-focus-button";
import { HeroForm } from "@/components/hero-form";
import { HeroForm } from "@/features/sihirbaz/components/hero-form";
import { Parallax } from "@/components/parallax";
import { Reveal } from "@/features/pazarlama/components/reveal";
import { SosyalKanitBandi } from "@/features/pazarlama/components/sosyal-kanit";

View File

@@ -1,7 +1,7 @@
import { Suspense } from "react";
import type { Metadata } from "next";
import { JsonLd, breadcrumbJsonLd } from "@/lib/seo";
import { CtaSiraForm } from "@/components/cta-sira-form";
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { SiteFooter } from "@/components/site-footer";
import { PagePixelDivider } from "@/components/pixel-decor";
import {

View File

@@ -21,7 +21,7 @@ import type {
RaporParams,
RaporSonuc,
} from "@/features/rapor/types/rapor";
import { sihirbazDogrula, type SihirbazSecimleri } from "@/lib/sihirbaz";
import { sihirbazDogrula, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
import { raporMaskele } from "@/lib/rapor-maske";

View File

@@ -4,12 +4,12 @@ import { PUAN_TURLERI, type PuanTuruKey } from "@/types/yokatlas";
import { getSession } from "@/lib/session";
import { kullanicininRaporu } from "@/lib/rapor-kaydi";
import { tadimlikSec } from "@/lib/tadimlik-havuzu";
import { SihirbazBolumu } from "./sihirbaz-cagri-karti";
import { SihirbazBolumu } from "@/features/sihirbaz/components/sihirbaz-cagri-karti";
import { TadimlikSatiri } from "./tadimlik-satiri";
import { ProgramTablosu } from "@/components/program-tablosu";
import { ManuelHarita } from "@/components/manuel-liste/manuel-harita";
import { SiteFooter } from "@/components/site-footer";
import { SiraGerekli } from "./sira-gerekli";
import { SiraGerekli } from "@/features/sihirbaz/components/sira-gerekli";
export const metadata: Metadata = {
title: "Tercih Listeni Kur",

View File

@@ -25,11 +25,8 @@ import { useGorunumOlayi } from "@/components/use-gorunum-olayi";
import { olay, siraKovasi } from "@/lib/analitik";
import { dilimdenRisk, riskHesapla } from "@/lib/risk";
import { turkishSlugify } from "@/lib/slug";
import {
PROFIL_DEGISTI_EVENT,
sonucHref,
tercihProfiliOku,
} from "@/lib/sihirbaz";
import { PROFIL_DEGISTI_EVENT, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliOku } from "@/features/sihirbaz/sihirbaz-profil";
import type { TadimlikSatir } from "@/lib/tadimlik-havuzu";
const GENEL = "genel";

View File

@@ -10,7 +10,7 @@ import {
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { TypingAnimation } from "@/components/ui/typing-animation";
import { SIHIRBAZ_AC_EVENT, sonucHref } from "@/lib/sihirbaz";
import { SIHIRBAZ_AC_EVENT, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
profilToplamaAc,
useTercihProfili,

View File

@@ -12,7 +12,7 @@ import { useRouter } from "next/navigation";
import { Wrench, X } from "lucide-react";
import { toast } from "sonner";
import { authClient } from "@/lib/auth-client";
import { tercihProfiliSil } from "@/lib/sihirbaz";
import { tercihProfiliSil } from "@/features/sihirbaz/sihirbaz-profil";
import {
devAnindaGiris,
devAyarla,

View File

@@ -13,7 +13,7 @@
import { eq } from "drizzle-orm";
import { getSession } from "@/lib/session";
import { appDb, schema } from "@/lib/appdb";
import { tercihProfiliDogrula, type TercihProfili } from "@/lib/sihirbaz";
import { tercihProfiliDogrula, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
MANUEL_LISTE_MAX,
dogrula,

View File

@@ -11,11 +11,8 @@
// - Sonrasında: liste/profil değişimleri ~2 sn debounce ile sunucuya yazılır.
import { useEffect, useRef } from "react";
import {
PROFIL_DEGISTI_EVENT,
tercihProfiliOku,
tercihProfiliYaz,
} from "@/lib/sihirbaz";
import { PROFIL_DEGISTI_EVENT } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliOku, tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
import { listeOku, sunucuylaBirlestir, useManuelListe } from "./store";
import { oturumDurumuBildir } from "./oturum-sinyali";
import { listeSenkronla, listeyiKaydet } from "./kayitli-liste-actions";

View File

@@ -5,13 +5,8 @@
import { useSyncExternalStore } from "react";
import type { Program } from "@/types/yokatlas";
import {
PROFIL_DEGISTI_EVENT,
sonucHref,
tercihProfiliOku,
tercihProfiliTamamlandiMi,
type TercihProfili,
} from "@/lib/sihirbaz";
import { PROFIL_DEGISTI_EVENT, sonucHref, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliOku, tercihProfiliTamamlandiMi } from "@/features/sihirbaz/sihirbaz-profil";
import {
ekle,
listedeMi,

View File

@@ -13,7 +13,7 @@ import {
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { RISK_ETIKET, type RiskSeviyesi } from "@/lib/risk";
import { sonucHref } from "@/lib/sihirbaz";
import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
tercihDegerlendir,
tercihListesiOzeti,

View File

@@ -8,10 +8,8 @@
import { useSyncExternalStore } from "react";
import type { Program } from "@/types/yokatlas";
import { riskHesapla } from "@/lib/risk";
import {
tercihProfiliOku,
type TercihProfili,
} from "@/lib/sihirbaz";
import { type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliOku } from "@/features/sihirbaz/sihirbaz-profil";
import {
MANUEL_LISTE_MAX,
dogrula,

View File

@@ -25,14 +25,11 @@ import {
import {
SihirbazAdimlarLazy,
preloadSihirbazAdimlar,
} from "@/components/sihirbaz-adimlar-lazy";
} from "@/features/sihirbaz/components/sihirbaz-adimlar-lazy";
import type { SihirbazFacetleri } from "@/types/yokatlas";
import { olay, siraKovasi } from "@/lib/analitik";
import {
tercihProfiliYaz,
type SihirbazSecimleri,
type TercihProfili,
} from "@/lib/sihirbaz";
import { type SihirbazSecimleri, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
import { authClient } from "@/lib/auth-client";
import {
profilKapisiniKapat,

View File

@@ -1,7 +1,7 @@
import Link from "next/link";
import { getAllBolumler, type BolumOzet } from "../katalog-queries";
import { KATEGORILER } from "@/lib/kategoriler";
import { CtaSiraForm } from "@/components/cta-sira-form";
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { PagePixelDivider } from "@/components/pixel-decor";
import { Skeleton } from "@/components/ui/skeleton";

View File

@@ -13,7 +13,7 @@ import {
sonucaGitIste,
useTercihProfili,
} from "@/components/manuel-liste/profil-kapisi-store";
import { PUAN_TURU_ETIKET } from "@/lib/sihirbaz";
import { PUAN_TURU_ETIKET } from "@/features/sihirbaz/sihirbaz-sabitler";
import { olay } from "@/lib/analitik";
import {
ArrowRight,

View File

@@ -10,7 +10,7 @@ import {
} from "../katalog-queries";
import { trBaslikDuzeni } from "@/lib/slug";
import { JsonLd, breadcrumbJsonLd, SITE_URL } from "@/lib/seo";
import { CtaSiraForm } from "@/components/cta-sira-form";
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { SiteFooter } from "@/components/site-footer";
import { Sayfalama, SAYFA_BOYU } from "./sayfalama";
import { PagePixelDivider } from "@/components/pixel-decor";

View File

@@ -1,7 +1,7 @@
import Link from "next/link";
import { getAllUniversiteler, type UniOzet } from "../katalog-queries";
import { trBaslikDuzeni } from "@/lib/slug";
import { CtaSiraForm } from "@/components/cta-sira-form";
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { PagePixelDivider } from "@/components/pixel-decor";
import { UniLogo } from "@/components/uni-logo";
import { Skeleton } from "@/components/ui/skeleton";

View File

@@ -4,7 +4,7 @@ import Link from "next/link";
import { ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
import { sonucHref } from "@/lib/sihirbaz";
import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
export function HeroFocusButton() {
function handleClick() {

View File

@@ -17,7 +17,7 @@ import {
import Link from "next/link";
import { ArrowRight } from "lucide-react";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
import { PUAN_TURU_ETIKET, sonucHref } from "@/lib/sihirbaz";
import { PUAN_TURU_ETIKET, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import type { DilimKey, SihirbazFacetleri } from "@/types/yokatlas";
export type DemoVeri = {

View File

@@ -3,7 +3,7 @@ import Link from "next/link";
import { notFound } from "next/navigation";
import { getAllRehberler, getAllRehberSlugs, getRehber } from "../rehber-queries";
import { JsonLd, articleJsonLd, breadcrumbJsonLd } from "@/lib/seo";
import { CtaSiraForm } from "@/components/cta-sira-form";
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { ElCizimiSema } from "./el-cizimi-sema";
import { RehberKapak } from "./rehber-kapak";
import { Skeleton } from "@/components/ui/skeleton";

View File

@@ -24,16 +24,13 @@ import { SectionEyebrow } from "@/components/pixel-decor";
import {
SihirbazAdimlarLazy,
preloadSihirbazAdimlar,
} from "@/components/sihirbaz-adimlar-lazy";
} from "./sihirbaz-adimlar-lazy";
import { authClient } from "@/lib/auth-client";
import { olay, siraKovasi } from "@/lib/analitik";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
import type { SihirbazFacetleri } from "@/types/yokatlas";
import {
sonucHref,
tercihProfiliYaz,
type SihirbazSecimleri,
} from "@/lib/sihirbaz";
import { sonucHref, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
// lib/db sunucu tarafı; etiketler client bundle'a sızmasın diye burada.
const PUAN_TURLERI_SECENEK = [

View File

@@ -15,7 +15,7 @@ import {
import {
SihirbazAdimlarLazy,
preloadSihirbazAdimlar,
} from "@/components/sihirbaz-adimlar-lazy";
} from "./sihirbaz-adimlar-lazy";
import { authClient } from "@/lib/auth-client";
import { olay, siraKovasi } from "@/lib/analitik";
import {
@@ -23,12 +23,8 @@ import {
useTercihProfili,
} from "@/components/manuel-liste/profil-kapisi-store";
import type { SihirbazFacetleri } from "@/types/yokatlas";
import {
PUAN_TURU_ETIKET,
sonucHref,
tercihProfiliYaz,
type SihirbazSecimleri,
} from "@/lib/sihirbaz";
import { PUAN_TURU_ETIKET, sonucHref, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
// lib/db sunucu tarafı; etiketler client bundle'a sızmasın diye burada.
const PUAN_TURLERI_SECENEK = [

View File

@@ -45,7 +45,7 @@ function SihirbazAdimlarSkeleton() {
export const SihirbazAdimlarLazy = dynamic(
() =>
import("@/components/sihirbaz-adimlar").then((m) => m.SihirbazAdimlar),
import("./sihirbaz-adimlar").then((m) => m.SihirbazAdimlar),
{
ssr: false,
loading: () => <SihirbazAdimlarSkeleton />,
@@ -54,5 +54,5 @@ export const SihirbazAdimlarLazy = dynamic(
/** Kullanıcı forma dokunduğu anda chunk'ı arka planda indir. */
export function preloadSihirbazAdimlar() {
void import("@/components/sihirbaz-adimlar");
void import("./sihirbaz-adimlar");
}

View File

@@ -15,17 +15,12 @@ import { toast } from "sonner";
import { cities } from "turkey-map-react/lib/data";
import { TransitionPanel } from "@/components/core/transition-panel";
import { Button } from "@/components/ui/button";
import { IlSecimHaritasi } from "@/components/il-secim-haritasi";
import { IlSecimHaritasi } from "./il-secim-haritasi";
import { normalizeIlAdi } from "@/lib/harita";
import { olay } from "@/lib/analitik";
import { trBaslikDuzeni } from "@/lib/slug";
import type { SihirbazFacetleri } from "@/types/yokatlas";
import {
ONCELIKLER,
UNIVERSITE_TIPI_ETIKET,
type SihirbazSecimleri,
type UniversiteTipi,
} from "@/lib/sihirbaz";
import { ONCELIKLER, UNIVERSITE_TIPI_ETIKET, type SihirbazSecimleri, type UniversiteTipi } from "@/features/sihirbaz/sihirbaz-sabitler";
export function Cip({
secili,

View File

@@ -11,13 +11,8 @@ import { PixelField } from "@/components/pixel-decor";
import { useGorunumOlayi } from "@/components/use-gorunum-olayi";
import { olay } from "@/lib/analitik";
import type { SihirbazFacetleri } from "@/types/yokatlas";
import {
SIHIRBAZ_AC_EVENT,
SIHIRBAZ_STORAGE_KEY,
sihirbazDogrula,
tercihProfiliYaz,
type SihirbazSecimleri,
} from "@/lib/sihirbaz";
import { SIHIRBAZ_AC_EVENT, SIHIRBAZ_STORAGE_KEY, sihirbazDogrula, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
import { SihirbazModal } from "./sihirbaz-modal";
// Üretim /listem'de koşar (bkz. listem/liste-uretici.tsx); sihirbaz

View File

@@ -6,9 +6,9 @@ import {
DialogDescription,
DialogTitle,
} from "@/components/ui/dialog";
import { SihirbazAdimlarLazy } from "@/components/sihirbaz-adimlar-lazy";
import { SihirbazAdimlarLazy } from "./sihirbaz-adimlar-lazy";
import type { SihirbazFacetleri } from "@/types/yokatlas";
import type { SihirbazSecimleri } from "@/lib/sihirbaz";
import type { SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
/**
* Sihirbaz modalı artık yalnızca adımları toplar; üretim, önizleme ve liste

View File

@@ -9,7 +9,7 @@ import Link from "next/link";
import { ArrowLeft, Trophy } from "lucide-react";
import { Button } from "@/components/ui/button";
import { PagePixelDivider } from "@/components/pixel-decor";
import { sonucHref } from "@/lib/sihirbaz";
import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
sonucaGitIste,
useProfilKapisi,

View File

@@ -0,0 +1,49 @@
// Ortak tercih profilinin localStorage katmanı — yalnızca client'ta anlamlı.
// Şema, doğrulama ve sabitler sihirbaz-sabitler.ts'te yaşar.
import {
PROFIL_DEGISTI_EVENT,
SIHIRBAZ_STORAGE_KEY,
tercihProfiliDogrula,
type TercihProfili,
} from "./sihirbaz-sabitler";
function profilDegistiginiYayinla(): void {
window.dispatchEvent(new Event(PROFIL_DEGISTI_EVENT));
}
/** Client'ta SIHIRBAZ_STORAGE_KEY'den doğrulanmış profil okur. */
export function tercihProfiliOku(): TercihProfili | null {
if (typeof window === "undefined") return null;
try {
const ham = localStorage.getItem(SIHIRBAZ_STORAGE_KEY);
if (!ham) return null;
return tercihProfiliDogrula(JSON.parse(ham));
} catch {
return null;
}
}
/** 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 {}
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 {}
profilDegistiginiYayinla();
}
export function tercihProfiliTamamlandiMi(): boolean {
return tercihProfiliOku() !== null;
}

View File

@@ -1,8 +1,10 @@
// Sonuç sayfasındaki sihirbaz modalının seçim şeması, doğrulaması ve prompt özeti.
// Sihirbazın seçim şeması, doğrulaması ve prompt özeti — izomorfik katman:
// hem client bileşenleri hem server action'ları/AI motoru buradan okur.
// localStorage'a dokunan profil yardımcıları sihirbaz-profil.ts'te yaşar.
// Kategoriler/iller sıralamaya göre dinamik üretilir (bkz. rankWindowFacets);
// öncelikler statik kalır (veriye bağlı değil, tercih niyeti).
import { KATEGORILER } from "./kategoriler";
import { KATEGORILER } from "@/lib/kategoriler";
import type { UniturGrubu } from "@/types/yokatlas";
export const ONCELIKLER = [
@@ -43,10 +45,6 @@ export const PROFIL_DEGISTI_EVENT = "kolaytercih:profil-degisti";
// orkestratörünü (SihirbazBolumu) bu olayla açar.
export const SIHIRBAZ_AC_EVENT = "kolaytercih:sihirbaz-ac";
function profilDegistiginiYayinla(): void {
window.dispatchEvent(new Event(PROFIL_DEGISTI_EVENT));
}
export interface SihirbazSecimleri {
kategoriler: string[];
iller: string[];
@@ -128,42 +126,6 @@ export function tercihProfiliDogrula(girdi: unknown): TercihProfili | null {
return { sira, tur: p.tur, secimler };
}
/** Client'ta SIHIRBAZ_STORAGE_KEY'den doğrulanmış profil okur. */
export function tercihProfiliOku(): TercihProfili | null {
if (typeof window === "undefined") return null;
try {
const ham = localStorage.getItem(SIHIRBAZ_STORAGE_KEY);
if (!ham) return null;
return tercihProfiliDogrula(JSON.parse(ham));
} catch {
return null;
}
}
/** 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 {}
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 {}
profilDegistiginiYayinla();
}
export function tercihProfiliTamamlandiMi(): boolean {
return tercihProfiliOku() !== null;
}
/** Profildeki sıra/tur ile sonuç sayfası URL'i — tüm uygulama aynı sorguyu kullanır. */
export function sonucHref(
profil: Pick<TercihProfili, "sira" | "tur">,

View File

@@ -17,7 +17,7 @@ import {
type Dilim,
type AdayProgram,
} from "../rapor-havuzu";
import { secimOzeti } from "../sihirbaz";
import { secimOzeti } from "@/features/sihirbaz/sihirbaz-sabitler";
import { RISK_ETIKET, dilimdenRisk, riskHesapla } from "../risk";
// Yapay zekâdan istenen küçük şema (kullanıcı kararı, 6 Ağu 2026): riskNotu

View File

@@ -1,6 +1,6 @@
import { kategoriEslesir } from "./kategoriler";
import { riskHesapla, type RiskSeviyesi } from "./risk";
import type { TercihProfili } from "./sihirbaz";
import type { TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
export type DegerlendirilecekProgram = {
isim: string;