merge: entegrasyon/guvenli-etiket — görünen 'Garanti' dilim adı 'Güvenli'
# Conflicts: # src/features/sihirbaz/components/cta-sira-form.tsx
This commit is contained in:
@@ -20,7 +20,7 @@ import type {
|
||||
PuanTuruKey,
|
||||
RankResultsListe,
|
||||
} from "@/types/yokatlas";
|
||||
import { riskHesapla, type RiskSeviyesi } from "@/lib/risk";
|
||||
import { DILIM_ETIKET, riskHesapla, type RiskSeviyesi } from "@/lib/risk";
|
||||
import { bolumSayfaSlug, uniSayfaSlug } from "@/lib/slug";
|
||||
import {
|
||||
ProgramSiraGecmisi,
|
||||
@@ -51,21 +51,21 @@ const DILIMLER: {
|
||||
}[] = [
|
||||
{
|
||||
key: "hayal",
|
||||
etiket: "Hayal",
|
||||
etiket: DILIM_ETIKET.hayal,
|
||||
icon: Rocket,
|
||||
renk: "text-red-500",
|
||||
renkAktif: "text-red-400",
|
||||
},
|
||||
{
|
||||
key: "dengeli",
|
||||
etiket: "Dengeli",
|
||||
etiket: DILIM_ETIKET.dengeli,
|
||||
icon: Scale,
|
||||
renk: "text-amber-500",
|
||||
renkAktif: "text-amber-400",
|
||||
},
|
||||
{
|
||||
key: "garanti",
|
||||
etiket: "Garanti",
|
||||
etiket: DILIM_ETIKET.garanti,
|
||||
icon: ShieldCheck,
|
||||
renk: "text-emerald-600",
|
||||
renkAktif: "text-emerald-400",
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { RISK_ETIKET, type RiskSeviyesi } from "@/lib/risk";
|
||||
import { DILIM_ETIKET, RISK_ETIKET, type RiskSeviyesi } from "@/lib/risk";
|
||||
import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
|
||||
import {
|
||||
tercihDegerlendir,
|
||||
@@ -156,9 +156,12 @@ export function SecimlerimPaneli() {
|
||||
|
||||
{ozet ? (
|
||||
<dl className="mt-4 grid grid-cols-2 gap-3 sm:grid-cols-4">
|
||||
<Istatistik etiket="Hayal" deger={ozet.hayal} />
|
||||
<Istatistik etiket="Dengeli" deger={ozet.dengeli} />
|
||||
<Istatistik etiket="Daha güvenli" deger={ozet.dahaGuvenli} />
|
||||
<Istatistik etiket={DILIM_ETIKET.hayal} deger={ozet.hayal} />
|
||||
<Istatistik etiket={DILIM_ETIKET.dengeli} deger={ozet.dengeli} />
|
||||
<Istatistik
|
||||
etiket={DILIM_ETIKET.garanti}
|
||||
deger={ozet.dahaGuvenli}
|
||||
/>
|
||||
<Istatistik etiket="Dikkat" deger={ozet.dikkat} />
|
||||
</dl>
|
||||
) : null}
|
||||
@@ -272,7 +275,9 @@ const SecimSatiri = memo(function SecimSatiri({
|
||||
/>
|
||||
) : null}
|
||||
{degerlendirme.riskEtiketi}
|
||||
{risk ? (
|
||||
{/* Dilim adı ile risk etiketi aynı kelimeyse ("Güvenli")
|
||||
parantez yazılmaz — "Güvenli (Güvenli)" olmasın. */}
|
||||
{risk && RISK_ETIKET[risk] !== degerlendirme.riskEtiketi ? (
|
||||
<span className="font-normal text-slate-500">
|
||||
({RISK_ETIKET[risk]})
|
||||
</span>
|
||||
|
||||
@@ -6,6 +6,8 @@ import { ElCizimiSema } from "@/features/rehber/components/el-cizimi-sema";
|
||||
|
||||
// Renkler ürünün risk dilinden (kırmızı/sarı/yeşil) ve slate paletinden;
|
||||
// renk tek başına anlam taşımaz, her düğüm metinle etiketlidir.
|
||||
// Üçüncü dilimin görünen adı "güvenli"dir; `classDef garanti` yalnızca iç
|
||||
// renk sınıfıdır (render edilmez), iç anahtarla aynı kalır.
|
||||
const SEMA = `---
|
||||
config:
|
||||
look: handDrawn
|
||||
@@ -25,7 +27,7 @@ flowchart TD
|
||||
R --> L("En fazla 24 tercihlik liste")
|
||||
L --> L1("üstte hayal — hedef 5, havuz elverdiğince")
|
||||
L --> L2("ortada dengeli — hedef 13, havuz elverdiğince")
|
||||
L --> L3("sonda garanti — hedef 6, havuz elverdiğince")
|
||||
L --> L3("sonda güvenli — hedef 6, havuz elverdiğince")
|
||||
|
||||
classDef havuz fill:#eff6ff,stroke:#3b82f6,color:#1e3a8a
|
||||
classDef uyari fill:#fffbeb,stroke:#f59e0b,color:#92400e
|
||||
@@ -42,7 +44,7 @@ export function HuniSemasi() {
|
||||
return (
|
||||
<ElCizimiSema
|
||||
tanim={SEMA}
|
||||
ariaLabel="Sihirbaz akış şeması: sıralamanla açılan programlar alan, il ve devlet/vakıf adımlarıyla aday havuzuna daraltılır; alanlar bölümün adına ve bağlı olduğu fakülteye göre belirlenir, il adımında programı olan tüm iller listelenir; havuz 24'ün altına düşerse filtreler gevşetilir, yine de dar kalırsa liste eldeki programlarla kurulur ve dağılım havuza uyarlanır; yapay zekâ havuzdan üstte hayal, ortada dengeli, sonda garanti olacak şekilde en fazla 24 tercih seçip her satıra gerekçe yazar; risk notu ve trend özeti gerçek sıralama geçmişinden hesaplanır."
|
||||
ariaLabel="Sihirbaz akış şeması: sıralamanla açılan programlar alan, il ve devlet/vakıf adımlarıyla aday havuzuna daraltılır; alanlar bölümün adına ve bağlı olduğu fakülteye göre belirlenir, il adımında programı olan tüm iller listelenir; havuz 24'ün altına düşerse filtreler gevşetilir, yine de dar kalırsa liste eldeki programlarla kurulur ve dağılım havuza uyarlanır; yapay zekâ havuzdan üstte hayal, ortada dengeli, sonda güvenli olacak şekilde en fazla 24 tercih seçip her satıra gerekçe yazar; risk notu ve trend özeti gerçek sıralama geçmişinden hesaplanır."
|
||||
figcaption={
|
||||
<>
|
||||
Her adım havuzu biraz daha daraltır; yapay zekâ listeyi bu havuzun{" "}
|
||||
|
||||
@@ -20,6 +20,7 @@ import { useTercihProfili } from "@/features/liste/hooks/use-tercih-profili";
|
||||
import { PUAN_TURU_ETIKET, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
|
||||
import type { DilimKey, SihirbazFacetleri } from "@/types/yokatlas";
|
||||
import { onbellekliJsonGetir } from "@/lib/istek-cache";
|
||||
import { DILIM_ETIKET } from "@/lib/risk";
|
||||
|
||||
export type DemoVeri = {
|
||||
facetler: SihirbazFacetleri;
|
||||
@@ -146,7 +147,7 @@ export function DilimSeridiCanli() {
|
||||
<svg
|
||||
viewBox="0 0 640 168"
|
||||
role="img"
|
||||
aria-label={`Sıralama ekseni: ${fmt(sira)}. sıradaki aday için Hayal diliminde ${fmt(t.hayal)}, Dengeli diliminde ${fmt(t.dengeli)}, Garanti diliminde ${fmt(t.garanti)} program var.`}
|
||||
aria-label={`Sıralama ekseni: ${fmt(sira)}. sıradaki aday için ${DILIM_ETIKET.hayal} diliminde ${fmt(t.hayal)}, ${DILIM_ETIKET.dengeli} diliminde ${fmt(t.dengeli)}, ${DILIM_ETIKET.garanti} diliminde ${fmt(t.garanti)} program var.`}
|
||||
className="w-full"
|
||||
>
|
||||
{/* eksen */}
|
||||
@@ -174,7 +175,7 @@ export function DilimSeridiCanli() {
|
||||
{/* hayal */}
|
||||
<rect x="20" y="70" width="150" height="32" rx="4" className="fill-red-100" />
|
||||
<text x="95" y="40" textAnchor="middle" className="fill-red-600 text-[12px] font-semibold">
|
||||
Hayal
|
||||
{DILIM_ETIKET.hayal}
|
||||
</text>
|
||||
<text x="95" y="56" textAnchor="middle" className="fill-slate-600 text-[11px] font-medium tabular-nums">
|
||||
{fmt(t.hayal)} program
|
||||
@@ -192,7 +193,7 @@ export function DilimSeridiCanli() {
|
||||
{/* dengeli */}
|
||||
<rect x="174" y="70" width="120" height="32" rx="4" className="fill-amber-100" />
|
||||
<text x="234" y="40" textAnchor="middle" className="fill-amber-600 text-[12px] font-semibold">
|
||||
Dengeli
|
||||
{DILIM_ETIKET.dengeli}
|
||||
</text>
|
||||
<text x="234" y="56" textAnchor="middle" className="fill-slate-600 text-[11px] font-medium tabular-nums">
|
||||
{fmt(t.dengeli)} program
|
||||
@@ -204,7 +205,7 @@ export function DilimSeridiCanli() {
|
||||
{/* garanti */}
|
||||
<rect x="296" y="70" width="324" height="32" rx="4" className="fill-emerald-100" />
|
||||
<text x="458" y="40" textAnchor="middle" className="fill-emerald-700 text-[12px] font-semibold">
|
||||
Garanti
|
||||
{DILIM_ETIKET.garanti}
|
||||
</text>
|
||||
<text x="458" y="56" textAnchor="middle" className="fill-slate-600 text-[11px] font-medium tabular-nums">
|
||||
{fmt(t.garanti)} program
|
||||
|
||||
@@ -68,12 +68,12 @@ export function MeraklisinaIcerik() {
|
||||
(listenin bel kemiği — sıralamanın yaklaşık yüzde kırk fazlasına
|
||||
kadar pay bırakılır), tabanı{" "}
|
||||
<strong>belirgin şekilde altında</strong> kalan her şey ise{" "}
|
||||
<span className="font-semibold text-emerald-600">Garanti</span>{" "}
|
||||
<span className="font-semibold text-emerald-600">Güvenli</span>{" "}
|
||||
dilimidir.
|
||||
</p>
|
||||
<DilimSeridiCanli />
|
||||
<p className="mt-4">
|
||||
Garanti diliminin bir sonu yok: 87. sıradaki bir adayın da 500
|
||||
Güvenli diliminin bir sonu yok: 87. sıradaki bir adayın da 500
|
||||
bininci sıradaki bir adayın da ulaşabildiği <em>bütün</em>{" "}
|
||||
programlar listededir. Liste sana en yakın tabandan başlar; aşağı
|
||||
indikçe ve “Daha fazla göster”e bastıkça senden
|
||||
@@ -131,7 +131,7 @@ export function MeraklisinaIcerik() {
|
||||
<p className="mt-2">
|
||||
Tüm bu hesaplar <strong>geçen yılların</strong>{" "}
|
||||
yerleştirme sonuçlarına dayanır. Kontenjanlar, tercih davranışları
|
||||
ve puanlar her yıl değişir; geçen yıl “garanti”
|
||||
ve puanlar her yıl değişir; geçen yıl “güvenli”
|
||||
görünen bir bölüm bu yıl dolabilir. Bu yüzden satırlarda son beş
|
||||
yılın taban seyrini de gösteririz — çizgi yukarı tırmanıyorsa
|
||||
bölüm zorlaşıyor demektir. KolayTercih karar <em>destek</em>{" "}
|
||||
|
||||
@@ -29,17 +29,14 @@ import {
|
||||
import { bolumSayfaSlug, uniSayfaSlug } from "@/lib/slug";
|
||||
import type { RaporSonuc } from "@/features/rapor/types/rapor";
|
||||
import {
|
||||
DILIM_ETIKET,
|
||||
RISK_ETIKET,
|
||||
dilimdenFarkliRiskEtiketi,
|
||||
dilimdenRisk,
|
||||
riskHesapla,
|
||||
type RiskSeviyesi,
|
||||
} from "@/lib/risk";
|
||||
|
||||
export const DILIM_ETIKET: Record<string, string> = {
|
||||
hayal: "Hayal",
|
||||
dengeli: "Dengeli",
|
||||
garanti: "Garanti",
|
||||
};
|
||||
import type { Dilim } from "@/lib/rapor-havuzu";
|
||||
|
||||
// Risk renk dili: yeşil = güvenli, sarı = az riskli, kırmızı = riskli.
|
||||
// Nokta hiçbir yerde tek başına durmaz; yanındaki etiket dar ekranda sr-only
|
||||
@@ -75,12 +72,16 @@ export function RaporSatirDetayi({
|
||||
trendOzeti: string;
|
||||
}) {
|
||||
const stil = RISK_STIL[risk];
|
||||
// Risk etiketi yalnızca dilimin varsayılanından farklıysa yazılır; yoksa
|
||||
// üçüncü dilimde başlık "Güvenli · Güvenli" olurdu (bkz. risk.ts).
|
||||
const farkliRisk = dilimdenFarkliRiskEtiketi(dilim, risk);
|
||||
return (
|
||||
<>
|
||||
<div className="mb-2 flex flex-wrap items-center gap-2 text-xs text-slate-500">
|
||||
<stil.icon className="size-3.5" aria-hidden />
|
||||
<span className="font-medium">
|
||||
{DILIM_ETIKET[dilim]} · {RISK_ETIKET[risk]}
|
||||
{DILIM_ETIKET[dilim as Dilim] ?? dilim}
|
||||
{farkliRisk ? ` · ${farkliRisk}` : null}
|
||||
</span>
|
||||
{unitur ? <span>· {unitur}</span> : null}
|
||||
</div>
|
||||
@@ -345,7 +346,7 @@ export function RaporListesi({
|
||||
<p className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900">
|
||||
Tercihlerine göre {rapor.kapsam.toplam} uygun program bulundu; listen{" "}
|
||||
{rapor.kapsam.dagilim.hayal} hayal · {rapor.kapsam.dagilim.dengeli}{" "}
|
||||
dengeli · {rapor.kapsam.dagilim.garanti} garanti olarak kuruldu. Daha
|
||||
dengeli · {rapor.kapsam.dagilim.garanti} güvenli olarak kuruldu. Daha
|
||||
fazla seçenek için alan veya il filtreni genişletebilirsin.
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -2,16 +2,19 @@ import Image from "next/image";
|
||||
import { redirect } from "next/navigation";
|
||||
import { verifySession, getCurrentUser } from "@/lib/session";
|
||||
import { kullanicininRaporu } from "../rapor-queries";
|
||||
import { PUAN_TURLERI } from "@/types/yokatlas";
|
||||
import { PUAN_TURLERI, type DilimKey } from "@/types/yokatlas";
|
||||
import { DILIM_ETIKET, RISK_ETIKET, dilimdenRisk } from "@/lib/risk";
|
||||
import type { RaporParams, RaporSonuc } from "../types/rapor";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { YazdirButonu } from "./yazdir-butonu";
|
||||
|
||||
const DILIM_LABEL: Record<string, string> = {
|
||||
hayal: "Hayal (Riskli)",
|
||||
dengeli: "Dengeli (Az riskli)",
|
||||
garanti: "Garanti (Güvenli)",
|
||||
};
|
||||
// Dilim sütunu: dilim adı + varsayılan riski. Üçüncü dilimde ikisi aynı
|
||||
// kelime ("Güvenli") olduğu için parantez düşer — "Güvenli (Güvenli)" yazmaz.
|
||||
function dilimLabel(dilim: DilimKey): string {
|
||||
const ad = DILIM_ETIKET[dilim] ?? dilim;
|
||||
const risk = RISK_ETIKET[dilimdenRisk(dilim)];
|
||||
return ad === risk ? ad : `${ad} (${risk})`;
|
||||
}
|
||||
|
||||
export async function RaporYazdir() {
|
||||
const session = await verifySession("/rapor/yazdir");
|
||||
@@ -50,7 +53,7 @@ export async function RaporYazdir() {
|
||||
Not: Tercihlerine göre {rapor.kapsam.toplam} uygun program bulundu;
|
||||
liste {rapor.kapsam.dagilim.hayal} hayal ·{" "}
|
||||
{rapor.kapsam.dagilim.dengeli} dengeli ·{" "}
|
||||
{rapor.kapsam.dagilim.garanti} garanti olarak kuruldu.
|
||||
{rapor.kapsam.dagilim.garanti} güvenli olarak kuruldu.
|
||||
</p>
|
||||
) : null}
|
||||
</header>
|
||||
@@ -91,7 +94,7 @@ export async function RaporYazdir() {
|
||||
{p?.universite} · {p?.il ?? "—"}
|
||||
</span>
|
||||
</td>
|
||||
<td className="py-2 pr-2">{DILIM_LABEL[t.dilim]}</td>
|
||||
<td className="py-2 pr-2">{dilimLabel(t.dilim)}</td>
|
||||
<td className="py-2 pr-2">{t.gerekce}</td>
|
||||
<td className="py-2 pr-2">{t.riskNotu}</td>
|
||||
<td className="py-2">{t.trendOzeti}</td>
|
||||
|
||||
@@ -76,7 +76,7 @@ export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
|
||||
onChange={(e) => setFeedback(e.target.value)}
|
||||
rows={2}
|
||||
maxLength={1000}
|
||||
placeholder="ör. İlk 5 tercihte daha fazla İstanbul olsun, garanti dilimini genişlet…"
|
||||
placeholder="ör. İlk 5 tercihte daha fazla İstanbul olsun, güvenli dilimi genişlet…"
|
||||
disabled={pending}
|
||||
className="w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
/>
|
||||
|
||||
@@ -161,7 +161,7 @@ export function CtaSiraForm({
|
||||
</h2>
|
||||
<p className="mt-2 text-sm leading-6 text-slate-600">
|
||||
Sıralaman kayıtlı ({profil.sira.toLocaleString("tr-TR")}. sıra) —
|
||||
gerçek YÖK Atlas verisiyle hayal, dengeli ve garanti dilimlerindeki
|
||||
gerçek YÖK Atlas verisiyle hayal, dengeli ve güvenli dilimlerindeki
|
||||
programların hazır.
|
||||
</p>
|
||||
<Link
|
||||
@@ -185,7 +185,7 @@ export function CtaSiraForm({
|
||||
</h2>
|
||||
<p className="mt-2 text-sm leading-6 text-slate-600">
|
||||
{aciklama ??
|
||||
"YKS başarı sıralamanı gir; gerçek YÖK Atlas verisiyle sıralamana uygun hayal, dengeli ve garanti dilimlerindeki programları anında listele. Ücretsiz, üyelik gerekmez."}
|
||||
"YKS başarı sıralamanı gir; gerçek YÖK Atlas verisiyle sıralamana uygun hayal, dengeli ve güvenli dilimlerindeki programları anında listele. Ücretsiz, üyelik gerekmez."}
|
||||
</p>
|
||||
<Button
|
||||
type="button"
|
||||
@@ -227,7 +227,7 @@ export function CtaSiraForm({
|
||||
</h2>
|
||||
<p className="mt-2 max-w-xl text-sm leading-6 text-slate-600">
|
||||
Puan türünü seç, başarı sıralamanı yaz; hayal, dengeli ve
|
||||
garanti dilimlerindeki programları bu sayfadan ayrılmadan
|
||||
güvenli dilimlerindeki programları bu sayfadan ayrılmadan
|
||||
gör. Ücretsiz, üyelik gerekmez.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -322,7 +322,7 @@ export function SihirbazBolumu({
|
||||
<p className="relative mx-auto mt-3 max-w-xl text-white/90">
|
||||
Tablodan elle eklemek her zaman serbest. Ama üç adımda ilgi
|
||||
alanlarını ve şehirlerini söylersen, yapay zekâ hayal, dengeli
|
||||
ve garanti dilimlerine dağıtılmış 24 tercihi — her satırı
|
||||
ve güvenli dilimlerine dağıtılmış 24 tercihi — her satırı
|
||||
yerleşme riski ve gerekçesiyle — senin yerine dizer.
|
||||
</p>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user