İlk commit: Stepstead web (statik panel + db)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
dea01dd6a8
18 changed files with 3764 additions and 0 deletions
119
db/index.html
Normal file
119
db/index.html
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<!doctype html>
|
||||
<html lang="tr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Stepstead — Craft Veritabanı</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<style>
|
||||
:root{
|
||||
--bg:#f5f3ee; --card:#fff; --ink:#2d3a2e; --muted:#77806f; --accent:#3a5a40;
|
||||
--line:#e4e0d6;
|
||||
--common:#6b7280; --uncommon:#2e8b45; --rare:#2563c9; --epic:#8b3fc9; --legendary:#c9762e;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{margin:0;font-family:system-ui,sans-serif;background:var(--bg);color:var(--ink)}
|
||||
header{background:var(--accent);color:#fff;padding:20px 16px;position:sticky;top:0;z-index:5;box-shadow:0 2px 12px rgba(0,0,0,.15)}
|
||||
header .inner{max-width:1000px;margin:0 auto}
|
||||
header h1{margin:0 0 2px;font-size:24px}
|
||||
header h1 a{color:#fff;text-decoration:none}
|
||||
header p{margin:0;font-size:13px;opacity:.85}
|
||||
.controls{max-width:1000px;margin:16px auto 0;padding:0 16px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
|
||||
#q{flex:1 1 220px;padding:10px 14px;border:1px solid var(--line);border-radius:8px;font-size:15px;background:var(--card)}
|
||||
.chip{padding:7px 14px;border-radius:999px;border:1px solid var(--line);background:var(--card);cursor:pointer;font-size:13px;white-space:nowrap}
|
||||
.chip.on{background:var(--accent);color:#fff;border-color:var(--accent)}
|
||||
main{max-width:1000px;margin:16px auto 60px;padding:0 16px}
|
||||
.stats{color:var(--muted);font-size:13px;margin:8px 2px 16px}
|
||||
h2.group{font-size:19px;margin:28px 0 4px;color:var(--accent);border-bottom:2px solid var(--line);padding-bottom:6px}
|
||||
h3.family{font-size:14px;margin:16px 0 8px;color:var(--muted);text-transform:uppercase;letter-spacing:.5px}
|
||||
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px}
|
||||
.card{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:12px 14px}
|
||||
.card .name{font-weight:600;font-size:15px}
|
||||
.card .meta{font-size:12px;color:var(--muted);margin:4px 0 8px;display:flex;gap:10px;flex-wrap:wrap}
|
||||
.card .ings{font-size:13px;line-height:1.5}
|
||||
.card .ings b{color:var(--muted);font-weight:500}
|
||||
.badge{display:inline-block;background:#e8f0e9;color:var(--accent);border-radius:6px;padding:1px 7px;font-size:12px;margin-left:6px}
|
||||
.r-common{color:var(--common)} .r-uncommon{color:var(--uncommon)} .r-rare{color:var(--rare)}
|
||||
.r-epic{color:var(--epic)} .r-legendary{color:var(--legendary)}
|
||||
.empty{color:var(--muted);text-align:center;margin:48px 0}
|
||||
</style>
|
||||
<script src="/nav.js?v=8" data-theme="light" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header><div class="inner">
|
||||
<h1><a href="/">Stepstead</a> · Craft Veritabanı</h1>
|
||||
<p>Tüm üretim tarifleri — malzemeler, skill gereksinimleri, adım maliyetleri</p>
|
||||
</div></header>
|
||||
|
||||
<div class="controls">
|
||||
<input id="q" type="search" placeholder="Tarif, malzeme veya skill ara… (örn. Meşe, Kılıç, Simya)">
|
||||
<div id="chips"></div>
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="stats" id="stats"></div>
|
||||
<div id="list"></div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
let DATA=null, activeGroup="Tümü";
|
||||
const norm=s=>s.toLocaleLowerCase("tr");
|
||||
|
||||
fetch("data/crafts.json").then(r=>r.json()).then(d=>{DATA=d;buildChips();render();});
|
||||
|
||||
function buildChips(){
|
||||
const box=document.getElementById("chips");
|
||||
const groups=["Tümü",...Object.keys(DATA.groups).sort((a,b)=>DATA.groups[b]-DATA.groups[a])];
|
||||
box.style.display="flex";box.style.flexWrap="wrap";box.style.gap="8px";
|
||||
for(const g of groups){
|
||||
const c=document.createElement("button");
|
||||
c.className="chip"+(g===activeGroup?" on":"");
|
||||
c.textContent=g==="Tümü"?`Tümü (${DATA.total})`:`${g} (${DATA.groups[g]})`;
|
||||
c.onclick=()=>{activeGroup=g;document.querySelectorAll(".chip").forEach(x=>x.classList.remove("on"));c.classList.add("on");render();};
|
||||
box.appendChild(c);
|
||||
}
|
||||
document.getElementById("q").addEventListener("input",render);
|
||||
}
|
||||
|
||||
function matches(r,q){
|
||||
if(!q)return true;
|
||||
if(norm(r.name).includes(q)||norm(r.skill).includes(q)||norm(r.family).includes(q)||norm(r.group).includes(q))return true;
|
||||
return r.ings.some(i=>norm(i.name).includes(q));
|
||||
}
|
||||
|
||||
function card(r){
|
||||
const eff=r.effect&&r.effect.type==="steps"?`<span class="badge">+${r.effect.amount} adım</span>`:"";
|
||||
const qty=r.out_qty>1?` ×${r.out_qty}`:"";
|
||||
const ings=r.ings.map(i=>`${i.qty}× <span class="r-${i.rarity}">${i.name}</span>`).join(", ");
|
||||
return `<div class="card">
|
||||
<div class="name"><span class="r-${r.rarity}">${r.name}</span>${qty}${eff}</div>
|
||||
<div class="meta"><span>⭐ ${r.skill} sv.${r.level}</span><span>👣 ${r.steps} adım</span><span>+${r.xp} XP</span></div>
|
||||
<div class="ings"><b>Malzeme:</b> ${ings}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function render(){
|
||||
const q=norm(document.getElementById("q").value.trim());
|
||||
const list=document.getElementById("list");
|
||||
const rows=DATA.recipes.filter(r=>(activeGroup==="Tümü"||r.group===activeGroup)&&matches(r,q));
|
||||
document.getElementById("stats").textContent=`${rows.length} tarif gösteriliyor`;
|
||||
if(!rows.length){list.innerHTML='<div class="empty">Sonuç yok.</div>';return;}
|
||||
// grup → aile → kartlar
|
||||
const byGroup={};
|
||||
for(const r of rows){(byGroup[r.group]??={});(byGroup[r.group][r.family]??=[]).push(r);}
|
||||
let html="";
|
||||
for(const g of Object.keys(byGroup).sort()){
|
||||
html+=`<h2 class="group">${g}</h2>`;
|
||||
const fams=Object.keys(byGroup[g]).sort((a,b)=>{
|
||||
const la=Math.min(...byGroup[g][a].map(r=>r.level)), lb=Math.min(...byGroup[g][b].map(r=>r.level));
|
||||
return la-lb||a.localeCompare(b,"tr");
|
||||
});
|
||||
for(const f of fams){
|
||||
if(f!=="Genel"||fams.length>1)html+=`<h3 class="family">${f} (${byGroup[g][f].length})</h3>`;
|
||||
html+=`<div class="grid">${byGroup[g][f].sort((a,b)=>a.level-b.level).map(card).join("")}</div>`;
|
||||
}
|
||||
}
|
||||
list.innerHTML=html;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue