diff --git a/src/app/api/soru/route.ts b/src/app/api/soru/route.ts index 9a5dfc9..7fe0123 100644 --- a/src/app/api/soru/route.ts +++ b/src/app/api/soru/route.ts @@ -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"; diff --git a/src/app/listem/liste-uretici.tsx b/src/app/listem/liste-uretici.tsx index 53ab4f3..3a95942 100644 --- a/src/app/listem/liste-uretici.tsx +++ b/src/app/listem/liste-uretici.tsx @@ -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…", diff --git a/src/app/listem/listem-bos-cta.tsx b/src/app/listem/listem-bos-cta.tsx index bf401bc..f08c56f 100644 --- a/src/app/listem/listem-bos-cta.tsx +++ b/src/app/listem/listem-bos-cta.tsx @@ -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 diff --git a/src/app/odeme/sonuc/rapor-yok-cta.tsx b/src/app/odeme/sonuc/rapor-yok-cta.tsx index 5c4d2d3..7b2bc68 100644 --- a/src/app/odeme/sonuc/rapor-yok-cta.tsx +++ b/src/app/odeme/sonuc/rapor-yok-cta.tsx @@ -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 diff --git a/src/app/page.tsx b/src/app/page.tsx index 3981de2..9728f11 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -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"; diff --git a/src/app/rehber/page.tsx b/src/app/rehber/page.tsx index 4d4590f..ce21288 100644 --- a/src/app/rehber/page.tsx +++ b/src/app/rehber/page.tsx @@ -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 { diff --git a/src/app/sonuc/actions.ts b/src/app/sonuc/actions.ts index 69b9ae9..2164d7c 100644 --- a/src/app/sonuc/actions.ts +++ b/src/app/sonuc/actions.ts @@ -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"; diff --git a/src/app/sonuc/page.tsx b/src/app/sonuc/page.tsx index d20b079..8cf27d0 100644 --- a/src/app/sonuc/page.tsx +++ b/src/app/sonuc/page.tsx @@ -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", diff --git a/src/app/sonuc/tadimlik-satiri.tsx b/src/app/sonuc/tadimlik-satiri.tsx index bd01e18..3e55470 100644 --- a/src/app/sonuc/tadimlik-satiri.tsx +++ b/src/app/sonuc/tadimlik-satiri.tsx @@ -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"; diff --git a/src/components/arama-funnel-karti.tsx b/src/components/arama-funnel-karti.tsx index fe0e364..84e6cec 100644 --- a/src/components/arama-funnel-karti.tsx +++ b/src/components/arama-funnel-karti.tsx @@ -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, diff --git a/src/components/dev/dev-panel.tsx b/src/components/dev/dev-panel.tsx index e37d8b3..a3aea11 100644 --- a/src/components/dev/dev-panel.tsx +++ b/src/components/dev/dev-panel.tsx @@ -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, diff --git a/src/components/manuel-liste/kayitli-liste-actions.ts b/src/components/manuel-liste/kayitli-liste-actions.ts index b810b69..fc2affe 100644 --- a/src/components/manuel-liste/kayitli-liste-actions.ts +++ b/src/components/manuel-liste/kayitli-liste-actions.ts @@ -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, diff --git a/src/components/manuel-liste/liste-senkron.tsx b/src/components/manuel-liste/liste-senkron.tsx index 98457d5..be6a298 100644 --- a/src/components/manuel-liste/liste-senkron.tsx +++ b/src/components/manuel-liste/liste-senkron.tsx @@ -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"; diff --git a/src/components/manuel-liste/profil-kapisi-store.ts b/src/components/manuel-liste/profil-kapisi-store.ts index 39d0fbd..afd9b7f 100644 --- a/src/components/manuel-liste/profil-kapisi-store.ts +++ b/src/components/manuel-liste/profil-kapisi-store.ts @@ -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, diff --git a/src/components/manuel-liste/secimlerim-paneli.tsx b/src/components/manuel-liste/secimlerim-paneli.tsx index 481c2cd..30ad6fe 100644 --- a/src/components/manuel-liste/secimlerim-paneli.tsx +++ b/src/components/manuel-liste/secimlerim-paneli.tsx @@ -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, diff --git a/src/components/manuel-liste/store.ts b/src/components/manuel-liste/store.ts index 388509b..1a1fabf 100644 --- a/src/components/manuel-liste/store.ts +++ b/src/components/manuel-liste/store.ts @@ -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, diff --git a/src/components/manuel-liste/tercih-profili-kapisi.tsx b/src/components/manuel-liste/tercih-profili-kapisi.tsx index bafe0dc..d6cd283 100644 --- a/src/components/manuel-liste/tercih-profili-kapisi.tsx +++ b/src/components/manuel-liste/tercih-profili-kapisi.tsx @@ -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, diff --git a/src/features/katalog/components/bolum-listesi.tsx b/src/features/katalog/components/bolum-listesi.tsx index 8da25b4..e1d88a6 100644 --- a/src/features/katalog/components/bolum-listesi.tsx +++ b/src/features/katalog/components/bolum-listesi.tsx @@ -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"; diff --git a/src/features/katalog/components/katalog-arama.tsx b/src/features/katalog/components/katalog-arama.tsx index 79ab40f..3d26f97 100644 --- a/src/features/katalog/components/katalog-arama.tsx +++ b/src/features/katalog/components/katalog-arama.tsx @@ -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, diff --git a/src/features/katalog/components/universite-icerik.tsx b/src/features/katalog/components/universite-icerik.tsx index d52e0f5..2e82786 100644 --- a/src/features/katalog/components/universite-icerik.tsx +++ b/src/features/katalog/components/universite-icerik.tsx @@ -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"; diff --git a/src/features/katalog/components/universite-listesi.tsx b/src/features/katalog/components/universite-listesi.tsx index 8608769..750ae6c 100644 --- a/src/features/katalog/components/universite-listesi.tsx +++ b/src/features/katalog/components/universite-listesi.tsx @@ -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"; diff --git a/src/features/pazarlama/components/hero-focus-button.tsx b/src/features/pazarlama/components/hero-focus-button.tsx index 47ba574..3ed43ee 100644 --- a/src/features/pazarlama/components/hero-focus-button.tsx +++ b/src/features/pazarlama/components/hero-focus-button.tsx @@ -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() { diff --git a/src/features/pazarlama/components/meraklisina-demo.tsx b/src/features/pazarlama/components/meraklisina-demo.tsx index 86a259f..c37fd8c 100644 --- a/src/features/pazarlama/components/meraklisina-demo.tsx +++ b/src/features/pazarlama/components/meraklisina-demo.tsx @@ -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 = { diff --git a/src/features/rehber/components/rehber-makale.tsx b/src/features/rehber/components/rehber-makale.tsx index 8f162a0..25d75bd 100644 --- a/src/features/rehber/components/rehber-makale.tsx +++ b/src/features/rehber/components/rehber-makale.tsx @@ -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"; diff --git a/src/components/cta-sira-form.tsx b/src/features/sihirbaz/components/cta-sira-form.tsx similarity index 98% rename from src/components/cta-sira-form.tsx rename to src/features/sihirbaz/components/cta-sira-form.tsx index 0611be5..37201a1 100644 --- a/src/components/cta-sira-form.tsx +++ b/src/features/sihirbaz/components/cta-sira-form.tsx @@ -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 = [ diff --git a/src/components/hero-form.tsx b/src/features/sihirbaz/components/hero-form.tsx similarity index 97% rename from src/components/hero-form.tsx rename to src/features/sihirbaz/components/hero-form.tsx index eb0343e..536cbc7 100644 --- a/src/components/hero-form.tsx +++ b/src/features/sihirbaz/components/hero-form.tsx @@ -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 = [ diff --git a/src/components/il-secim-haritasi.tsx b/src/features/sihirbaz/components/il-secim-haritasi.tsx similarity index 100% rename from src/components/il-secim-haritasi.tsx rename to src/features/sihirbaz/components/il-secim-haritasi.tsx diff --git a/src/components/sihirbaz-adimlar-lazy.tsx b/src/features/sihirbaz/components/sihirbaz-adimlar-lazy.tsx similarity index 93% rename from src/components/sihirbaz-adimlar-lazy.tsx rename to src/features/sihirbaz/components/sihirbaz-adimlar-lazy.tsx index 201dbc8..03cff3b 100644 --- a/src/components/sihirbaz-adimlar-lazy.tsx +++ b/src/features/sihirbaz/components/sihirbaz-adimlar-lazy.tsx @@ -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: () => , @@ -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"); } diff --git a/src/components/sihirbaz-adimlar.tsx b/src/features/sihirbaz/components/sihirbaz-adimlar.tsx similarity index 98% rename from src/components/sihirbaz-adimlar.tsx rename to src/features/sihirbaz/components/sihirbaz-adimlar.tsx index 8cbf570..2197bd3 100644 --- a/src/components/sihirbaz-adimlar.tsx +++ b/src/features/sihirbaz/components/sihirbaz-adimlar.tsx @@ -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, diff --git a/src/app/sonuc/sihirbaz-cagri-karti.tsx b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx similarity index 98% rename from src/app/sonuc/sihirbaz-cagri-karti.tsx rename to src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx index 32721ae..4a4412b 100644 --- a/src/app/sonuc/sihirbaz-cagri-karti.tsx +++ b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx @@ -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 diff --git a/src/app/sonuc/sihirbaz-modal.tsx b/src/features/sihirbaz/components/sihirbaz-modal.tsx similarity index 91% rename from src/app/sonuc/sihirbaz-modal.tsx rename to src/features/sihirbaz/components/sihirbaz-modal.tsx index 79b928a..ee87813 100644 --- a/src/app/sonuc/sihirbaz-modal.tsx +++ b/src/features/sihirbaz/components/sihirbaz-modal.tsx @@ -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 diff --git a/src/app/sonuc/sira-gerekli.tsx b/src/features/sihirbaz/components/sira-gerekli.tsx similarity index 97% rename from src/app/sonuc/sira-gerekli.tsx rename to src/features/sihirbaz/components/sira-gerekli.tsx index aa84c48..4c9cc12 100644 --- a/src/app/sonuc/sira-gerekli.tsx +++ b/src/features/sihirbaz/components/sira-gerekli.tsx @@ -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, diff --git a/src/features/sihirbaz/sihirbaz-profil.ts b/src/features/sihirbaz/sihirbaz-profil.ts new file mode 100644 index 0000000..77bc42a --- /dev/null +++ b/src/features/sihirbaz/sihirbaz-profil.ts @@ -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; +} diff --git a/src/lib/sihirbaz.ts b/src/features/sihirbaz/sihirbaz-sabitler.ts similarity index 77% rename from src/lib/sihirbaz.ts rename to src/features/sihirbaz/sihirbaz-sabitler.ts index a3e485c..1e6a948 100644 --- a/src/lib/sihirbaz.ts +++ b/src/features/sihirbaz/sihirbaz-sabitler.ts @@ -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, diff --git a/src/lib/ai/rapor.ts b/src/lib/ai/rapor.ts index e0bcb95..7d6e305 100644 --- a/src/lib/ai/rapor.ts +++ b/src/lib/ai/rapor.ts @@ -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 diff --git a/src/lib/tercih-degerlendirme.ts b/src/lib/tercih-degerlendirme.ts index fd5e86a..7a54aed 100644 --- a/src/lib/tercih-degerlendirme.ts +++ b/src/lib/tercih-degerlendirme.ts @@ -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;