Update package.json scripts, enhance layout with new components, and improve API error handling
Some checks failed
Deploy / deploy (push) Failing after 1h28m6s

- Added new scripts for database operations and temporary production in package.json.
- Integrated KaydetBannerLazy component into the layout for improved user notifications.
- Enhanced API error handling in the soru route to mark credit exhaustion.
- Updated the IletisimPage for better button styling and user experience.
- Refactored ListemPage to streamline user flow and improve session handling.
- Removed unused ListePaneli component to clean up the codebase.
This commit is contained in:
bilalgursen
2026-08-06 02:27:42 +03:00
parent 488845ae1f
commit e62c6f07df
77 changed files with 4132 additions and 1659 deletions

85
src/lib/harita-pinler.ts Normal file
View File

@@ -0,0 +1,85 @@
// Rapordan Türkiye haritası pinleri türetir — /sonuc ve /listem ortak kullanır.
import type { RaporSonuc } from "@/lib/ai/rapor";
import type { HaritaPin } from "@/components/tercih-haritasi";
import { ilKonum, uniAdiNormalize, uniKonum } from "@/lib/harita";
import { dilimdenRisk, riskHesapla, type RiskSeviyesi } from "@/lib/risk";
const RISK_AGIRLIK: Record<RiskSeviyesi, number> = {
guvenli: 0,
"az-riskli": 1,
riskli: 2,
};
/**
* Rapordan harita pinleri türetir. Açık satırlar üniversite bazında gruplanır
* (kampüs konumunda, adıyla); kilitli satırlar il başına tek adsız "?" pinine
* toplanır — maskeli veride üniversite adı zaten client'a inmediği için
* harita paywall'ı delemez. Haritada karşılığı olmayan tercihler sayılır.
*/
export function pinleriTuret(
rapor: RaporSonuc,
adaySira: number,
kilitliBaslangic: number,
): { pinler: HaritaPin[]; haritaDisi: number } {
const gruplar = new Map<string, HaritaPin>();
let haritaDisi = 0;
rapor.tercihler.forEach((t, i) => {
const p = rapor.programlar[t.programId];
if (!p) return;
const risk = riskHesapla(p.efektifSira, adaySira) ?? dilimdenRisk(t.dilim);
const kilitli = i >= kilitliBaslangic;
if (kilitli) {
const konum = ilKonum(p.il);
if (!konum) {
haritaDisi += 1;
return;
}
const key = `kilit|${p.il}`;
const mevcut = gruplar.get(key);
if (mevcut) {
mevcut.tercihSiralari.push(t.sira);
if (RISK_AGIRLIK[risk] > RISK_AGIRLIK[mevcut.risk]) mevcut.risk = risk;
} else {
// Açık pinlerle üst üste binmesin diye il merkezinin hafif altına
gruplar.set(key, {
id: key,
universite: "",
il: p.il,
x: konum.x,
y: konum.y + 9,
tercihSiralari: [t.sira],
risk,
kilitli: true,
});
}
return;
}
const konum = uniKonum(p.universite, p.il);
if (!konum) {
haritaDisi += 1;
return;
}
const key = `${uniAdiNormalize(p.universite)}|${p.il ?? ""}`;
const mevcut = gruplar.get(key);
if (mevcut) {
mevcut.tercihSiralari.push(t.sira);
if (RISK_AGIRLIK[risk] > RISK_AGIRLIK[mevcut.risk]) mevcut.risk = risk;
} else {
gruplar.set(key, {
id: key,
universite: p.universite,
il: p.il,
x: konum.x,
y: konum.y,
tercihSiralari: [t.sira],
risk,
});
}
});
return { pinler: [...gruplar.values()], haritaDisi };
}