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:
@@ -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";
|
||||
|
||||
|
||||
@@ -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…",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 = [
|
||||
@@ -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 = [
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,
|
||||
49
src/features/sihirbaz/sihirbaz-profil.ts
Normal file
49
src/features/sihirbaz/sihirbaz-profil.ts
Normal 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;
|
||||
}
|
||||
@@ -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">,
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user