Update terminology from "AI" to "Yapay Zeka" across multiple components for consistency and clarity. Adjusted button labels, error messages, and comments to reflect the new terminology, enhancing user understanding and maintaining uniformity throughout the application.
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
bilalgursen
2026-08-02 04:57:15 +03:00
parent a8bd13ef43
commit 205743f3b1
23 changed files with 51 additions and 51 deletions

View File

@@ -63,7 +63,7 @@ rozet, buton varyantı tasarlanmaz.
anlamlı olmalı (renk/ikon tek başına anlam taşımaz — ürünün risk renk dili anlamlı olmalı (renk/ikon tek başına anlam taşımaz — ürünün risk renk dili
kuralıyla aynı ilke). kuralıyla aynı ilke).
- Buton etiketleri eylemin sonucunu söyler: "Programları gör" (girdi adımı), - Buton etiketleri eylemin sonucunu söyler: "Programları gör" (girdi adımı),
"Ücretsiz tablonu gör" / "AI listemi kur (3 kredi)" (sihirbaz sonu, girişe göre). "Ücretsiz tablonu gör" / "Yapay Zeka listemi kur (3 kredi)" (sihirbaz sonu, girişe göre).
## 5. Davranış ve teknik algı ## 5. Davranış ve teknik algı

View File

@@ -229,7 +229,7 @@ export async function POST(request: NextRequest) {
reason: "refund", reason: "refund",
refId: kullaniciMesajId, refId: kullaniciMesajId,
}); });
console.error("[soru] AI istemcisi kurulamadı (anahtar eksik olabilir)"); console.error("[soru] Yapay Zeka istemcisi kurulamadı (anahtar eksik olabilir)");
return Response.json( return Response.json(
{ {
error: error:
@@ -260,7 +260,7 @@ export async function POST(request: NextRequest) {
}); });
} catch { } catch {
await grantCredits({ userId, delta: 1, reason: "refund", refId: kullaniciMesajId }); await grantCredits({ userId, delta: 1, reason: "refund", refId: kullaniciMesajId });
return Response.json({ error: "AI'ya ulaşılamadı." }, { status: 502 }); return Response.json({ error: "Yapay Zeka'ya ulaşılamadı." }, { status: 502 });
} }
const readable = new ReadableStream({ const readable = new ReadableStream({

View File

@@ -45,7 +45,7 @@ export default async function GirisPage({
<> <>
Kayıt olduğunda{" "} Kayıt olduğunda{" "}
<span className="font-semibold">5 deneme kredisi</span>{" "} <span className="font-semibold">5 deneme kredisi</span>{" "}
hesabına tanımlanır AI danışmana ücretsiz soru sorabilirsin. hesabına tanımlanır Yapay Zeka danışmana ücretsiz soru sorabilirsin.
</> </>
)} )}
</p> </p>

View File

@@ -19,8 +19,8 @@ export function ListemBosCta() {
<> <>
<p className="mt-3 text-slate-600"> <p className="mt-3 text-slate-600">
{profil {profil
? "Sıralaman kayıtlı — birkaç adımda 24 tercihlik risk analizli listeni kur; sonra burada görüntüleyip AI danışmanla üzerinde konuşabilirsin." ? "Sıralaman kayıtlı — birkaç adımda 24 tercihlik risk analizli listeni kur; sonra burada görüntüleyip Yapay Zeka danışmanla üzerinde konuşabilirsin."
: "Sıralamanı girip birkaç adımda 24 tercihlik risk analizli listeni kur; sonra burada görüntüleyip AI danışmanla üzerinde konuşabilirsin."} : "Sıralamanı girip birkaç adımda 24 tercihlik risk analizli listeni kur; sonra burada görüntüleyip Yapay Zeka danışmanla üzerinde konuşabilirsin."}
</p> </p>
<PagePixelDivider seed={67} className="mx-auto mt-6" /> <PagePixelDivider seed={67} className="mx-auto mt-6" />
<Button <Button
@@ -29,7 +29,7 @@ export function ListemBosCta() {
className="mt-6 h-12 cursor-pointer bg-orange-500 px-8 text-white hover:bg-orange-600" className="mt-6 h-12 cursor-pointer bg-orange-500 px-8 text-white hover:bg-orange-600"
> >
<Link href={profil ? sonucHref(profil, { sihirbaz: "1" }) : "/"}> <Link href={profil ? sonucHref(profil, { sihirbaz: "1" }) : "/"}>
{profil ? "AI listeni kur" : "Sıralamanı gir, AI listeni kur"} {profil ? "Yapay Zeka listeni kur" : "Sıralamanı gir, Yapay Zeka listeni kur"}
<ArrowRight className="size-4" aria-hidden /> <ArrowRight className="size-4" aria-hidden />
</Link> </Link>
</Button> </Button>

View File

@@ -74,7 +74,7 @@ export default async function ListemPage({
<section className="mx-auto flex max-w-2xl flex-col items-center px-4 py-16 text-center"> <section className="mx-auto flex max-w-2xl flex-col items-center px-4 py-16 text-center">
<Sparkles className="size-10 text-primary" aria-hidden /> <Sparkles className="size-10 text-primary" aria-hidden />
<h1 className="mt-4 font-heading text-2xl font-bold"> <h1 className="mt-4 font-heading text-2xl font-bold">
Henüz AI listen yok Henüz Yapay Zeka listen yok
</h1> </h1>
<ListemBosCta /> <ListemBosCta />
</section> </section>
@@ -118,8 +118,8 @@ export default async function ListemPage({
) : null} ) : null}
<h1 className="max-w-2xl font-heading text-xl font-bold tracking-tight sm:text-2xl"> <h1 className="max-w-2xl font-heading text-xl font-bold tracking-tight sm:text-2xl">
{user.hasPaket {user.hasPaket
? "AI tercih listen" ? "Yapay Zeka tercih listen"
: "Veriyi ücretsiz incele. Kararı AI ile netleştir."} : "Veriyi ücretsiz incele. Kararı Yapay Zeka ile netleştir."}
</h1> </h1>
{user.hasPaket ? ( {user.hasPaket ? (
<p className="mt-2 max-w-2xl text-sm leading-6 text-slate-600"> <p className="mt-2 max-w-2xl text-sm leading-6 text-slate-600">
@@ -178,11 +178,11 @@ export default async function ListemPage({
</span> </span>
<div> <div>
<p className="font-heading font-bold text-slate-900"> <p className="font-heading font-bold text-slate-900">
İlk {ACIK_SATIR} tercihte AI analizini gördün İlk {ACIK_SATIR} tercihte Yapay Zeka analizini gördün
</p> </p>
<p className="mt-1 max-w-xl text-sm text-slate-600"> <p className="mt-1 max-w-xl text-sm text-slate-600">
Kalan {24 - ACIK_SATIR} tercihin kişisel risk, gerekçe ve Kalan {24 - ACIK_SATIR} tercihin kişisel risk, gerekçe ve
AI yorumu paketle ılır. Program adları ve taban Yapay Zeka yorumu paketle ılır. Program adları ve taban
verileri her zaman ücretsiz. verileri her zaman ücretsiz.
</p> </p>
</div> </div>
@@ -234,9 +234,9 @@ export default async function ListemPage({
<ul className="flex flex-col gap-3 text-sm"> <ul className="flex flex-col gap-3 text-sm">
{[ {[
"24 tercihin tamamında kişisel risk analizi", "24 tercihin tamamında kişisel risk analizi",
"Her program için kısa, gerekçeli AI yorumu", "Her program için kısa, gerekçeli Yapay Zeka yorumu",
"2 liste revizyonu ve paylaşılabilir PDF", "2 liste revizyonu ve paylaşılabilir PDF",
`${URUNLER.paket.credits} AI danışman sorusu`, `${URUNLER.paket.credits} Yapay Zeka danışman sorusu`,
].map((ozellik) => ( ].map((ozellik) => (
<li key={ozellik} className="flex items-start gap-2.5"> <li key={ozellik} className="flex items-start gap-2.5">
<Check <Check

View File

@@ -140,7 +140,7 @@ export default function MeraklisinaPage() {
4. Sihirbaz süzer, yapay zekâ kurar 4. Sihirbaz süzer, yapay zekâ kurar
</h2> </h2>
<p className="mt-2"> <p className="mt-2">
&ldquo;AI listemi kur&rdquo; sihirbazındaki üç adım birbirinden &ldquo;Yapay Zeka listemi kur&rdquo; sihirbazındaki üç adım birbirinden
bağımsız değildir. İlk adımda yalnızca{" "} bağımsız değildir. İlk adımda yalnızca{" "}
<strong>sıralamanla ulaşabildiğin</strong>{" "} <strong>sıralamanla ulaşabildiğin</strong>{" "}
alanlar listelenir; ikinci adımdaki iller, seçtiğin alanlardaki alanlar listelenir; ikinci adımdaki iller, seçtiğin alanlardaki

View File

@@ -7,7 +7,7 @@ import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store"
import { sonucHref } from "@/lib/sihirbaz"; import { sonucHref } from "@/lib/sihirbaz";
/** /**
* Ödeme başarılı ama henüz AI listesi yokken gösterilen CTA: kayıtlı tercih * Ödeme başarılı ama henüz Yapay Zeka listesi yokken gösterilen CTA: kayıtlı tercih
* profili olan adayı sihirbazıık hâlde sonuç sayfasına götürür ve * profili olan adayı sihirbazıık hâlde sonuç sayfasına götürür ve
* "sıralamanı gir" metni gösterilmez; profil yoksa ana sayfadaki sıralama * "sıralamanı gir" metni gösterilmez; profil yoksa ana sayfadaki sıralama
* formuna yönlendirir. * formuna yönlendirir.

View File

@@ -41,7 +41,7 @@ const OZELLIKLER = [
{ icon: RefreshCcw, text: "2 liste revizyon hakkı" }, { icon: RefreshCcw, text: "2 liste revizyon hakkı" },
{ {
icon: MessageCircleQuestion, icon: MessageCircleQuestion,
text: `${URUNLER.paket.credits} AI danışman sorusu (her mesaj 1 kredi)`, text: `${URUNLER.paket.credits} Yapay Zeka danışman sorusu (her mesaj 1 kredi)`,
}, },
] as const; ] as const;

View File

@@ -192,7 +192,7 @@ export function ListePaneli({
<p className="mt-1 text-sm text-slate-500"> <p className="mt-1 text-sm text-slate-500">
{sira.toLocaleString("tr-TR")}. sıra ·{" "} {sira.toLocaleString("tr-TR")}. sıra ·{" "}
{kilitli {kilitli
? `tüm taban verileri açık · ${ACIK_SATIR} AI analiz örneği` ? `tüm taban verileri açık · ${ACIK_SATIR} Yapay Zeka analiz örneği`
: `${kredi} kredin kaldı`} : `${kredi} kredin kaldı`}
</p> </p>
</div> </div>
@@ -248,7 +248,7 @@ export function ListePaneli({
</p> </p>
<p className="mt-1 max-w-xl text-sm text-slate-600"> <p className="mt-1 max-w-xl text-sm text-slate-600">
Paket; kalan {24 - ACIK_SATIR} tercih için kişisel risk, Paket; kalan {24 - ACIK_SATIR} tercih için kişisel risk,
gerekçe, PDF, 2 revizyon ve 60 AI danışman sorusunu açar. gerekçe, PDF, 2 revizyon ve 60 Yapay Zeka danışman sorusunu açar.
</p> </p>
{kredi > 0 ? ( {kredi > 0 ? (
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-slate-500">
@@ -278,7 +278,7 @@ export function ListePaneli({
</div> </div>
) : null} ) : null}
{/* AI danışman: sağ altta yüzen buton, alttan popup olarak açılır */} {/* Yapay Zeka danışman: sağ altta yüzen buton, alttan popup olarak açılır */}
<SohbetPopup kredi={kredi} /> <SohbetPopup kredi={kredi} />
</section> </section>
); );

View File

@@ -67,7 +67,7 @@ export default async function SonucPage({
: [null, null]; : [null, null];
const facetler = rankWindowFacets(sira, turKey); const facetler = rankWindowFacets(sira, turKey);
// AI'sız ham liste: yalnızca sıralamayla ulaşılabilen programlar (dilimli) // Yapay Zeka'sız ham liste: yalnızca sıralamayla ulaşılabilen programlar (dilimli)
const hamSonuclar = searchByRank(sira, turKey, { limitPerBucket: 20 }); const hamSonuclar = searchByRank(sira, turKey, { limitPerBucket: 20 });
// Paketsize giden rapor sunucuda maskelenir: blur yalnızca CSS olduğundan // Paketsize giden rapor sunucuda maskelenir: blur yalnızca CSS olduğundan
// kilitli satırların gerçek içeriği client'a hiç inmez. // kilitli satırların gerçek içeriği client'a hiç inmez.
@@ -90,11 +90,11 @@ export default async function SonucPage({
buraya canlı yansır. */} buraya canlı yansır. */}
<ManuelHarita /> <ManuelHarita />
{/* AI'dan bağımsız ham tablo — haritanın hemen altında, sayfanın ana {/* Yapay Zeka'dan bağımsız ham tablo — haritanın hemen altında, sayfanın ana
gövdesi; puan türü navbar'daki sıralama rozetinden değiştirilir */} gövdesi; puan türü navbar'daki sıralama rozetinden değiştirilir */}
<ProgramTablosu sonuclar={hamSonuclar} adaySira={sira} tur={turKey} /> <ProgramTablosu sonuclar={hamSonuclar} adaySira={sira} tur={turKey} />
{/* Sihirbaz akışı (CTA + modal + AI listesi) — blurlu AI paneli {/* Sihirbaz akışı (CTA + modal + Yapay Zeka listesi) — blurlu Yapay Zeka paneli
sayfanın en altında yaşar */} sayfanın en altında yaşar */}
<SihirbazBolumu <SihirbazBolumu
sira={sira} sira={sira}

View File

@@ -223,7 +223,7 @@ export function SihirbazBolumu({
setKredi(sonuc.kredi); setKredi(sonuc.kredi);
setPaketli(sonuc.hasPaket); setPaketli(sonuc.hasPaket);
tercihProfiliSil(); tercihProfiliSil();
// AI çıktısı bu sayfada gösterilmez: üretim animasyonu açık kalır, // Yapay Zeka çıktısı bu sayfada gösterilmez: üretim animasyonu açık kalır,
// liste (paketsizse paywall'lı hâliyle) /listem'de karşılar. // liste (paketsizse paywall'lı hâliyle) /listem'de karşılar.
router.push("/listem"); router.push("/listem");
return; return;
@@ -337,7 +337,7 @@ export function SihirbazBolumu({
return ( return (
<> <>
{/* AI çıktısı (rapor listesi/haritası) bu sayfada render edilmez; {/* Yapay Zeka çıktısı (rapor listesi/haritası) bu sayfada render edilmez;
panel yalnızca üretim ve kredi-yetersiz gibi geçici funnel panel yalnızca üretim ve kredi-yetersiz gibi geçici funnel
durumlarını gösterir, listenin kendisi /listem'de yaşar. */} durumlarını gösterir, listenin kendisi /listem'de yaşar. */}
<div ref={bolumRef} className="relative"> <div ref={bolumRef} className="relative">
@@ -431,11 +431,11 @@ export function SihirbazBolumu({
<PixelField seed={13} /> <PixelField seed={13} />
</div> </div>
<h2 className="relative font-heading text-2xl font-bold sm:text-3xl"> <h2 className="relative font-heading text-2xl font-bold sm:text-3xl">
Seçimlerin hazır AI listen bir adım uzakta Seçimlerin hazır Yapay Zeka listen bir adım uzakta
</h2> </h2>
<p className="relative mx-auto mt-3 max-w-xl text-white/90"> <p className="relative mx-auto mt-3 max-w-xl text-white/90">
Yukarıdaki tablo her zaman ücretsiz. 5 deneme kredinle 24 Yukarıdaki tablo her zaman ücretsiz. 5 deneme kredinle 24
tercihlik AI listeni de kurabilirsin: ücretsiz giriş yap, tercihlik Yapay Zeka listeni de kurabilirsin: ücretsiz giriş yap,
seçimlerin kayıtlı listen otomatik kurulsun (üretim 3 seçimlerin kayıtlı listen otomatik kurulsun (üretim 3
kredi, kalan 2 kredinle danışmana soru sorarsın). kredi, kalan 2 kredinle danışmana soru sorarsın).
</p> </p>
@@ -445,7 +445,7 @@ export function SihirbazBolumu({
className="relative mt-6 h-auto min-h-12 w-full cursor-pointer whitespace-normal bg-orange-500 px-4 py-3 text-white transition-colors duration-200 hover:bg-orange-600 sm:w-auto sm:px-8" className="relative mt-6 h-auto min-h-12 w-full cursor-pointer whitespace-normal bg-orange-500 px-4 py-3 text-white transition-colors duration-200 hover:bg-orange-600 sm:w-auto sm:px-8"
> >
<Link href={girisUrl}> <Link href={girisUrl}>
5 deneme kredinle AI listeni kur giriş yap 5 deneme kredinle Yapay Zeka listeni kur giriş yap
<ArrowRight className="size-4" aria-hidden /> <ArrowRight className="size-4" aria-hidden />
</Link> </Link>
</Button> </Button>
@@ -475,7 +475,7 @@ export function SihirbazBolumu({
onClick={sihirbaziBaslat} onClick={sihirbaziBaslat}
className="relative mt-6 h-auto min-h-12 w-full cursor-pointer whitespace-normal bg-orange-500 px-4 py-3 text-white transition-colors duration-200 hover:bg-orange-600 sm:w-auto sm:px-8" className="relative mt-6 h-auto min-h-12 w-full cursor-pointer whitespace-normal bg-orange-500 px-4 py-3 text-white transition-colors duration-200 hover:bg-orange-600 sm:w-auto sm:px-8"
> >
AI listemi kur Yapay Zeka listemi kur
<ArrowRight className="size-4" aria-hidden /> <ArrowRight className="size-4" aria-hidden />
</Button> </Button>
</section> </section>
@@ -492,7 +492,7 @@ export function SihirbazBolumu({
<div className="flex-1"> <div className="flex-1">
<p className="font-heading text-sm font-bold text-slate-900"> <p className="font-heading text-sm font-bold text-slate-900">
{girisBekliyor {girisBekliyor
? "Seçimlerin kayıtlıAI listen hazır bekliyor" ? "Seçimlerin kayıtlıYapay Zeka listen hazır bekliyor"
: "Tek tek ekleme, yapay zekâ kursun"} : "Tek tek ekleme, yapay zekâ kursun"}
</p> </p>
<p className="text-xs text-slate-500"> <p className="text-xs text-slate-500">
@@ -549,7 +549,7 @@ export function SihirbazBolumu({
sonSecimler ?? (bekleyen?.eslesir ? bekleyen.secimler : null) sonSecimler ?? (bekleyen?.eslesir ? bekleyen.secimler : null)
} }
sonButonEtiketi={ sonButonEtiketi={
girisliMi ? "AI listemi kur (3 kredi)" : "Giriş yap ve listeni gör" girisliMi ? "Yapay Zeka listemi kur (3 kredi)" : "Giriş yap ve listeni gör"
} }
onTamamla={ilerle} onTamamla={ilerle}
/> />

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
// AI danışman sohbeti — sayfa altında yüzen buton + intercom tarzı popup. // Yapay Zeka danışman sohbeti — sayfa altında yüzen buton + intercom tarzı popup.
// Motion dili: panel tetikleyicisinden doğar (transform-origin sağ-alt), // Motion dili: panel tetikleyicisinden doğar (transform-origin sağ-alt),
// spring ile açılır; çıkış girişten hızlı. Reduced motion'da cross-fade. // spring ile açılır; çıkış girişten hızlı. Reduced motion'da cross-fade.

View File

@@ -136,7 +136,7 @@ export function AramaFunnelKarti({ onSec }: { onSec: () => void }) {
onClick={sihirbazaGit} onClick={sihirbazaGit}
className="h-11 w-full shrink-0 cursor-pointer rounded-xl bg-orange-500 px-5 font-semibold text-white shadow-[0_8px_24px_rgba(249,115,22,0.28)] transition-[background-color,transform,box-shadow] duration-200 hover:bg-orange-400 hover:shadow-[0_10px_28px_rgba(249,115,22,0.36)] active:scale-[0.98] focus-visible:ring-white/70 sm:w-auto" className="h-11 w-full shrink-0 cursor-pointer rounded-xl bg-orange-500 px-5 font-semibold text-white shadow-[0_8px_24px_rgba(249,115,22,0.28)] transition-[background-color,transform,box-shadow] duration-200 hover:bg-orange-400 hover:shadow-[0_10px_28px_rgba(249,115,22,0.36)] active:scale-[0.98] focus-visible:ring-white/70 sm:w-auto"
> >
AI listemi kur Yapay Zeka listemi kur
<ArrowRight className="size-4" aria-hidden /> <ArrowRight className="size-4" aria-hidden />
</Button> </Button>
</div> </div>

View File

@@ -303,7 +303,7 @@ export function CtaSiraForm({ baslik }: { baslik?: string }) {
tur={tur} tur={tur}
facetler={facetler} facetler={facetler}
sonButonEtiketi={ sonButonEtiketi={
girisli ? "AI listemi kur (3 kredi)" : "Ücretsiz tablonu gör" girisli ? "Yapay Zeka listemi kur (3 kredi)" : "Ücretsiz tablonu gör"
} }
onTamamla={secimleriTamamla} onTamamla={secimleriTamamla}
/> />

View File

@@ -186,7 +186,7 @@ export function HeroForm() {
disabled={yukleniyor} disabled={yukleniyor}
className="h-12 cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600" className="h-12 cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600"
> >
{yukleniyor ? "Hazırlanıyor…" : "AI listemi kur"} {yukleniyor ? "Hazırlanıyor…" : "Yapay Zeka listemi kur"}
<ArrowRight className="size-4" aria-hidden /> <ArrowRight className="size-4" aria-hidden />
</Button> </Button>
</form> </form>
@@ -214,7 +214,7 @@ export function HeroForm() {
tur={tur} tur={tur}
facetler={facetler} facetler={facetler}
sonButonEtiketi={ sonButonEtiketi={
girisli ? "AI listemi kur (3 kredi)" : "Ücretsiz tablonu gör" girisli ? "Yapay Zeka listemi kur (3 kredi)" : "Ücretsiz tablonu gör"
} }
onTamamla={secimleriTamamla} onTamamla={secimleriTamamla}
/> />

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
// Navbar'daki "Seçtiklerim" butonu: elle kurulan aday listesinin sayacını // Navbar'daki "Seçtiklerim" butonu: elle kurulan aday listesinin sayacını
// taşır, tıklanınca çekmeceyi açar/kapatır. ("Listem" adı AI raporunun // taşır, tıklanınca çekmeceyi açar/kapatır. ("Listem" adı Yapay Zeka raporunun
// yaşadığı /listem sayfasına aittir — isim çakışmasın.) // yaşadığı /listem sayfasına aittir — isim çakışmasın.)
import { ListChecks } from "lucide-react"; import { ListChecks } from "lucide-react";

View File

@@ -82,7 +82,7 @@ function yukle() {
profiliTazele(); profiliTazele();
yayinla(); yayinla();
}); });
// Aynı sekmedeki yazmalar (hero formu, AI sihirbazı) storage olayı // Aynı sekmedeki yazmalar (hero formu, Yapay Zeka sihirbazı) storage olayı
// tetiklemez; tercihProfiliYaz/Sil bu olayı yayınlar. // tetiklemez; tercihProfiliYaz/Sil bu olayı yayınlar.
window.addEventListener(PROFIL_DEGISTI_EVENT, () => { window.addEventListener(PROFIL_DEGISTI_EVENT, () => {
profiliTazele(); profiliTazele();

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
// Manuel 24'lük liste — AI'dan bağımsız, kullanıcının tablodan "+" ile kendi // Manuel 24'lük liste — Yapay Zeka'dan bağımsız, kullanıcının tablodan "+" ile kendi
// kurduğu tercih listesi. Kaynak tek: bu modüldeki harici store. Navbar rozeti, // kurduğu tercih listesi. Kaynak tek: bu modüldeki harici store. Navbar rozeti,
// çekmece ve program tablosu aynı store'a abone olur; kalıcılık localStorage'ta // çekmece ve program tablosu aynı store'a abone olur; kalıcılık localStorage'ta
// (girişsiz kullanıcı da liste kurabilsin diye sunucuya yazmıyoruz). // (girişsiz kullanıcı da liste kurabilsin diye sunucuya yazmıyoruz).

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
// Sonuç sayfasının AI'sız ham listesi: yalnızca başarı sıralamasıyla // Sonuç sayfasının Yapay Zeka'sız ham listesi: yalnızca başarı sıralamasıyla
// yokatlas'tan gelen programlar, dilim sekmeleri halinde ve yakından uzağa // yokatlas'tan gelen programlar, dilim sekmeleri halinde ve yakından uzağa
// sayfalanır ("daha fazla göster" /api/programlar'dan akıtır). Her satırın "+" // sayfalanır ("daha fazla göster" /api/programlar'dan akıtır). Her satırın "+"
// butonu programı manuel 24'lük listeye ekler (bkz. manuel-liste/store). // butonu programı manuel 24'lük listeye ekler (bkz. manuel-liste/store).

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
// 24'lük listenin gövdesi. Program adı, 2024/2025 tabanları ve ham trend // 24'lük listenin gövdesi. Program adı, 2024/2025 tabanları ve ham trend
// herkese görünür. AI gerekçesi ile kişisel risk, kilitliBaslangic sonrasında // herkese görünür. Yapay Zeka gerekçesi ile kişisel risk, kilitliBaslangic sonrasında
// ücretli katman olarak ayrılır; ücretli metin sunucuda zaten maskelidir. // ücretli katman olarak ayrılır; ücretli metin sunucuda zaten maskelidir.
import { Fragment, useEffect, useRef, useState } from "react"; import { Fragment, useEffect, useRef, useState } from "react";
@@ -327,7 +327,7 @@ export function RaporListesi({
<div className="flex flex-col justify-center rounded-lg border border-dashed border-slate-300 bg-white p-3 sm:col-span-2"> <div className="flex flex-col justify-center rounded-lg border border-dashed border-slate-300 bg-white p-3 sm:col-span-2">
<dt className="flex items-center gap-1.5 text-xs font-semibold text-slate-700"> <dt className="flex items-center gap-1.5 text-xs font-semibold text-slate-700">
<Lock className="size-3.5" aria-hidden /> <Lock className="size-3.5" aria-hidden />
AI karar desteği Yapay Zeka karar desteği
</dt> </dt>
<dd className="mt-1 text-sm text-slate-600"> <dd className="mt-1 text-sm text-slate-600">
Bu bölümün neden listende olduğunu ve sıralamana özel yerleşme Bu bölümün neden listende olduğunu ve sıralamana özel yerleşme
@@ -344,7 +344,7 @@ export function RaporListesi({
</div> </div>
<div className="rounded-lg border border-slate-200 bg-white p-3"> <div className="rounded-lg border border-slate-200 bg-white p-3">
<dt className="text-xs font-semibold text-slate-500"> <dt className="text-xs font-semibold text-slate-500">
Risk ve AI yorumu Risk ve Yapay Zeka yorumu
</dt> </dt>
<dd className="mt-1 text-slate-700"> <dd className="mt-1 text-slate-700">
{t.riskNotu} {t.trendOzeti} {t.riskNotu} {t.trendOzeti}
@@ -420,7 +420,7 @@ export function RaporListesi({
<span className="text-right">2024 taban</span> <span className="text-right">2024 taban</span>
<span className="text-right">2025 taban</span> <span className="text-right">2025 taban</span>
<span>Ham trend</span> <span>Ham trend</span>
<span>AI risk</span> <span>Yapay Zeka risk</span>
<span className="w-4" /> <span className="w-4" />
</div> </div>

View File

@@ -85,7 +85,7 @@ function programBilgisi(p: AdayProgram): RaporSonuc["programlar"][string] {
// --- Dev mock: API key yokken (yalnızca development) gerçek havuzdan sahte // --- Dev mock: API key yokken (yalnızca development) gerçek havuzdan sahte
// ama tutarlı bir rapor üret. Akış (kredi, blur, risk renkleri, revizyon) // ama tutarlı bir rapor üret. Akış (kredi, blur, risk renkleri, revizyon)
// gerçek AI olmadan uçtan uca test edilebilsin diye. Prod'da asla çalışmaz. // gerçek Yapay Zeka olmadan uçtan uca test edilebilsin diye. Prod'da asla çalışmaz.
function mockAktif(): boolean { function mockAktif(): boolean {
return ( return (
@@ -140,7 +140,7 @@ function mockRapor(
return { return {
tercihler, tercihler,
genelDegerlendirme: `(Dev mock — ANTHROPIC_API_KEY tanımlı değil, bu rapor gerçek AI çıktısı değildir.) ${params.sira.toLocaleString( genelDegerlendirme: `(Dev mock — ANTHROPIC_API_KEY tanımlı değil, bu rapor gerçek Yapay Zeka çıktısı değildir.) ${params.sira.toLocaleString(
"tr-TR", "tr-TR",
)}. sıra için hayal/dengeli/garanti dağılımlı 24 tercihlik örnek liste kuruldu.${ )}. sıra için hayal/dengeli/garanti dağılımlı 24 tercihlik örnek liste kuruldu.${
revizyonNotu ? ` Revizyon isteğin not alındı: "${revizyonNotu}".` : "" revizyonNotu ? ` Revizyon isteğin not alındı: "${revizyonNotu}".` : ""
@@ -183,7 +183,7 @@ export async function raporUret(
); );
} }
// Dev'de API key yoksa gerçek AI yerine mock rapor (üretim gecikmesi taklidi) // Dev'de API key yoksa gerçek Yapay Zeka yerine mock rapor (üretim gecikmesi taklidi)
if (mockAktif()) { if (mockAktif()) {
await new Promise((r) => setTimeout(r, 1500)); await new Promise((r) => setTimeout(r, 1500));
return mockRapor(havuz, params, revizyonNotu); return mockRapor(havuz, params, revizyonNotu);

View File

@@ -1,6 +1,6 @@
// Paketsiz kullanıcıya giden raporun sunucu tarafı maskesi. // Paketsiz kullanıcıya giden raporun sunucu tarafı maskesi.
// YÖK Atlas'ın ham program ve taban sıralaması verileri ücretsiz kalır. // YÖK Atlas'ın ham program ve taban sıralaması verileri ücretsiz kalır.
// Yalnızca AI'ın ürettiği kişisel gerekçe/risk/trend yorumu maskelenir; // Yalnızca Yapay Zeka'nın ürettiği kişisel gerekçe/risk/trend yorumu maskelenir;
// böylece istemciye ücretli analiz metni hiç inmez. // böylece istemciye ücretli analiz metni hiç inmez.
import type { RaporSonuc } from "./ai/rapor"; import type { RaporSonuc } from "./ai/rapor";
@@ -12,7 +12,7 @@ const SAHTE_GEREKCE =
const SAHTE_RISK = const SAHTE_RISK =
"Sıralamana özel yerleşme riski paketle açılır."; "Sıralamana özel yerleşme riski paketle açılır.";
const SAHTE_TREND = const SAHTE_TREND =
"Ham trend verisi ücretsizdir; AI yorumu paketle açılır."; "Ham trend verisi ücretsizdir; Yapay Zeka yorumu paketle açılır.";
/** genelDegerlendirme'nin yalnızca ilk 1-2 cümlesini bırakır. */ /** genelDegerlendirme'nin yalnızca ilk 1-2 cümlesini bırakır. */
function degerlendirmeKirp(metin: string): string { function degerlendirmeKirp(metin: string): string {

View File

@@ -140,7 +140,7 @@ export function tercihProfiliOku(): TercihProfili | null {
} }
} }
/** Ortak profili yazar; hero ve AI sihirbazıyla aynı anahtarı kullanır. */ /** Ortak profili yazar; hero ve Yapay Zeka sihirbazıyla aynı anahtarı kullanır. */
export function tercihProfiliYaz(profil: TercihProfili): void { export function tercihProfiliYaz(profil: TercihProfili): void {
if (typeof window === "undefined") return; if (typeof window === "undefined") return;
const dogru = tercihProfiliDogrula(profil); const dogru = tercihProfiliDogrula(profil);
@@ -151,7 +151,7 @@ export function tercihProfiliYaz(profil: TercihProfili): void {
profilDegistiginiYayinla(); profilDegistiginiYayinla();
} }
/** Profili siler (ör. AI listesi üretilip seçimler tüketildiğinde). */ /** Profili siler (ör. Yapay Zeka listesi üretilip seçimler tüketildiğinde). */
export function tercihProfiliSil(): void { export function tercihProfiliSil(): void {
if (typeof window === "undefined") return; if (typeof window === "undefined") return;
try { try {