stepstead-web/items/index.html
jts dea01dd6a8 İlk commit: Stepstead web (statik panel + db)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:30:59 +03:00

158 lines
7.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="tr">
<head>
<meta charset="utf-8">
<title>Stepstead — Eşyalar</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)}
.row{max-width:1000px;margin:8px auto 0;padding:0 16px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.row .lbl{font-size:12px;color:var(--muted);margin-right:2px}
.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)}
.chip.cls.on{background:#2f4a6b;border-color:#2f4a6b}
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}
.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 6px;display:flex;gap:10px;flex-wrap:wrap}
.card .line{font-size:12.5px;line-height:1.5;margin-top:3px}
.card .line b{color:var(--muted);font-weight:500}
.tag{display:inline-block;border-radius:6px;padding:1px 7px;font-size:11.5px;margin:1px 3px 1px 0}
.tag.slot{background:#e8f0e9;color:var(--accent)}
.tag.cls{background:#e6ecf5;color:#2f4a6b}
.tag.all{background:#eef2ec;color:var(--muted)}
.tag.src{background:#f3ecdd;color:#8a6a2e}
.tag.eff{background:#e9f3f0;color:#2e7d6b}
.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> · Eşyalar</h1>
<p>Tüm silah, giysi, alet ve maddeler — hangi sınıf kullanır, nereden gelir</p>
</div></header>
<div class="controls">
<input id="q" type="search" placeholder="Eşya ara… (örn. Kılıç, Asa, Bakır, Çanta)">
</div>
<div class="row" id="typechips"></div>
<div class="row" id="clschips"><span class="lbl">Sınıf:</span></div>
<main>
<div class="stats" id="stats"></div>
<div id="list"></div>
</main>
<script>
let DATA=null, activeType="Tümü", activeClass=null;
const norm=s=>s.toLocaleLowerCase("tr");
const RORDER={common:0,uncommon:1,rare:2,epic:3,legendary:4};
fetch("data/items.json").then(r=>r.json()).then(d=>{DATA=d;buildChips();render();});
function chip(text,on,cls,fn){
const c=document.createElement("button");
c.className="chip"+(cls?" cls":"")+(on?" on":"");
c.textContent=text; c.onclick=fn; return c;
}
function buildChips(){
const tb=document.getElementById("typechips");
const types=["Tümü",...Object.keys(DATA.types).sort((a,b)=>DATA.types[b]-DATA.types[a])];
for(const t of types){
tb.appendChild(chip(t==="Tümü"?`Tümü (${DATA.total})`:`${t} (${DATA.types[t]})`,t===activeType,false,()=>{
activeType=t;document.querySelectorAll("#typechips .chip").forEach(x=>x.classList.remove("on"));
event.target.classList.add("on");render();
}));
}
const cb=document.getElementById("clschips");
cb.appendChild(chip("Hepsi",true,true,()=>{
activeClass=null;document.querySelectorAll("#clschips .chip").forEach(x=>x.classList.remove("on"));
event.target.classList.add("on");render();
}));
for(const c of DATA.classes){
cb.appendChild(chip(c,false,true,()=>{
activeClass=c;document.querySelectorAll("#clschips .chip").forEach(x=>x.classList.remove("on"));
event.target.classList.add("on");render();
}));
}
document.getElementById("q").addEventListener("input",render);
}
// sınıf filtresi: eşyayı verilen sınıf kullanabiliyor mu?
function usableBy(it,cls){
if(!cls)return true;
if(it.classes.length===0)return true; // herkese açık
return it.classes.includes(cls);
}
function matches(it,q){
if(!q)return true;
return norm(it.name).includes(q)||norm(it.type).includes(q)||
(it.slot&&norm(it.slot).includes(q))||it.classes.some(c=>norm(c).includes(q))||
it.gather.some(g=>norm(g.loc).includes(q)||norm(g.skill).includes(q));
}
function card(it){
const slot=it.slot?`<span class="tag slot">${it.slot}${it.two_handed?" (çift el)":""}</span>`:"";
let cls="";
if(it.slot_code&&it.slot_code!=="tool"){
cls=it.classes.length===0
? `<span class="tag all">Tüm sınıflar</span>`
: it.classes.map(c=>`<span class="tag cls">${c}</span>`).join("");
}
const src=[];
it.gather.forEach(g=>src.push(`<span class="tag src">📍 ${g.loc} · ${g.skill}</span>`));
if(it.craftable)src.push(`<span class="tag src">🔨 Üretilebilir</span>`);
const eff=it.effect&&it.effect.type==="steps"?`<span class="tag eff">+${it.effect.amount} adım</span>`:"";
const clsLine=(it.slot_code&&it.slot_code!=="tool")?`<div class="line"><b>Kullanabilen:</b> ${cls}</div>`:"";
const srcLine=src.length?`<div class="line"><b>Kaynak:</b> ${src.join(" ")}</div>`:"";
const descLine=it.desc?`<div class="line" style="color:var(--muted)">${it.desc}</div>`:"";
return `<div class="card">
<div class="name"><span class="r-${it.rarity}">${it.name}</span> ${slot} ${eff}</div>
<div class="meta"><span>${it.type}</span><span>🪙 ${it.value}</span></div>
${clsLine}${srcLine}${descLine}
</div>`;
}
function render(){
const q=norm(document.getElementById("q").value.trim());
const list=document.getElementById("list");
let rows=DATA.items.filter(it=>
(activeType==="Tümü"||it.type===activeType)&&usableBy(it,activeClass)&&matches(it,q));
document.getElementById("stats").textContent=
`${rows.length} eşya`+(activeClass?` · ${activeClass} kullanabilir`:"");
if(!rows.length){list.innerHTML='<div class="empty">Sonuç yok.</div>';return;}
const byType={};
for(const it of rows)(byType[it.type]??=[]).push(it);
let html="";
for(const t of Object.keys(byType).sort((a,b)=>byType[b].length-byType[a].length)){
html+=`<h2 class="group">${t} (${byType[t].length})</h2>`;
const sorted=byType[t].sort((a,b)=>
(RORDER[a.rarity]-RORDER[b.rarity])||a.name.localeCompare(b.name,"tr"));
html+=`<div class="grid">${sorted.map(card).join("")}</div>`;
}
list.innerHTML=html;
}
</script>
</body>
</html>