/* ============================================================
public/js/buildings/bazaar.js
============================================================ */
const BAZAAR_PER_PAGE = 18;
let baz_initialized = false;
let baz_page = 1;
let baz_wood = 0, baz_iron = 0, baz_gold = 0, baz_gems = 0;
const BAZ_SVG_RANGE = ``;
const BAZ_SVG_RACE = ``;
const RARITY_CRYSTALS = {
1:"roter-cristal.png",2:"blauer-cristal.png",3:"gelber-cristal.png",
4:"gruener-cristal.png",5:"oranger-cristal.png",6:"violet-cristal.png",7:"pinker-cristal.png"
};
function rarityImgs(rarity, size=11) {
const file = RARITY_CRYSTALS[String(rarity)];
if (!file) return "";
const img = `
`;
return img.repeat(parseInt(rarity)||0);
}
function loadCSS() {
if (!document.querySelector('link[href="/css/bazaar.css"]')) {
const l = document.createElement("link");
l.rel = "stylesheet"; l.href = "/css/bazaar.css";
document.head.appendChild(l);
}
}
function ensurePopup() {
if (document.getElementById("bazaar-popup")) return;
const popup = document.createElement("div");
popup.id = "bazaar-popup";
popup.className = "qm-popup";
popup.innerHTML = `
`;
document.body.appendChild(popup);
popup.querySelector("#bazaar-close").addEventListener("click", closeBazaar);
popup.querySelectorAll(".mp-tab").forEach((btn) => {
btn.addEventListener("click", () => {
popup.querySelectorAll(".mp-tab").forEach(t => t.classList.remove("mp-tab-active"));
popup.querySelectorAll(".mp-panel").forEach(p => p.classList.remove("active"));
btn.classList.add("mp-tab-active");
document.getElementById(btn.dataset.tab)?.classList.add("active");
});
});
/* Drag */
const header = popup.querySelector(".qm-popup-header");
let dragging=false, sx,sy,sl,st;
header.style.cursor="grab";
header.addEventListener("mousedown",(e)=>{
if(e.target.classList.contains("qm-popup-close"))return;
dragging=true; header.style.cursor="grabbing";
const r=popup.getBoundingClientRect();
sx=e.clientX;sy=e.clientY;sl=r.left;st=r.top;
popup.style.transform="none";
popup.style.left=sl+"px";popup.style.top=st+"px";
e.preventDefault();
});
document.addEventListener("mousemove",(e)=>{
if(!dragging)return;
popup.style.left=(sl+(e.clientX-sx))+"px";
popup.style.top=(st+(e.clientY-sy))+"px";
});
document.addEventListener("mouseup",()=>{dragging=false;header.style.cursor="grab";});
}
function updateCurrencyDisplay() {
const fmt = n => n.toLocaleString("de-DE");
const w=document.getElementById("baz-wood"); if(w) w.textContent=fmt(baz_wood);
const i=document.getElementById("baz-iron"); if(i) i.textContent=fmt(baz_iron);
const g=document.getElementById("baz-gold"); if(g) g.textContent=fmt(baz_gold);
const d=document.getElementById("baz-gems"); if(d) d.textContent=fmt(baz_gems);
}
async function loadShopCards() {
const grid = document.getElementById("baz-grid");
const pagination = document.getElementById("baz-pagination");
if (!grid) return;
grid.innerHTML = `Lade Karten…
`;
if (pagination) pagination.innerHTML = "";
try {
const res = await fetch(`/api/bazaar/cards?page=${baz_page}&limit=${BAZAAR_PER_PAGE}`);
if (!res.ok) throw new Error(res.status);
const data = await res.json();
baz_wood=data.wood; baz_iron=data.iron; baz_gold=data.gold; baz_gems=data.gems;
updateCurrencyDisplay();
if (!data.cards.length) {
grid.innerHTML = `Keine Karten verfĂĽgbar.
`;
return;
}
grid.innerHTML = data.cards.map((c) => {
const prices = [
c.price_wood > 0 ? `🪵 ${c.price_wood}` : "",
c.price_iron > 0 ? `⚙️ ${c.price_iron}` : "",
c.price_gold > 0 ? `🪙 ${c.price_gold}` : "",
c.price_gems > 0 ? `đź’Ž ${c.price_gems}` : "",
].filter(Boolean).join("");
return `

${c.attack != null ? `
${c.attack}` : ""}
${c.defends != null ? `
${c.defends}` : ""}
${c.cooldown != null ? `
${c.cooldown}` : ""}
${c.rarity ? `
${rarityImgs(c.rarity,11)}
` : ""}
${(c.range != null || c.race != null) ? `
${c.range != null ? `${BAZ_SVG_RANGE} ${c.range}` : ""}
${c.race != null ? `${BAZ_SVG_RACE} ${c.race}` : ""}
` : ""}
${prices || "Kostenlos"}
`;
}).join("");
grid.querySelectorAll(".baz-card").forEach((el) => {
el.addEventListener("click", () => {
const card = data.cards.find(c => c.id === parseInt(el.dataset.cardId));
if (card) showBuyConfirm(card);
});
});
renderPagination(pagination, data.totalPages, data.total);
} catch (err) {
grid.innerHTML = `Fehler beim Laden.
`;
console.error("[bazaar]", err);
}
}
function showBuyConfirm(card) {
document.getElementById("baz-confirm-modal")?.remove();
const canAfford =
baz_wood >= card.price_wood &&
baz_iron >= card.price_iron &&
baz_gold >= card.price_gold &&
baz_gems >= card.price_gems;
const priceStr = [
card.price_wood > 0 ? `🪵 ${card.price_wood} Holz` : "",
card.price_iron > 0 ? `⚙️ ${card.price_iron} Eisen` : "",
card.price_gold > 0 ? `🪙 ${card.price_gold} Gold` : "",
card.price_gems > 0 ? `đź’Ž ${card.price_gems} Gems` : "",
].filter(Boolean).join(" ");
const modal = document.createElement("div");
modal.id = "baz-confirm-modal";
modal.innerHTML = `
${card.name}
${priceStr || "Kostenlos"}
${!canAfford ? `
âš Nicht genug Ressourcen
` : ""}
`;
document.getElementById("bazaar-popup").appendChild(modal);
modal.querySelector("#baz-cancel").onclick = () => modal.remove();
modal.querySelector(".baz-confirm-backdrop").onclick = () => modal.remove();
modal.querySelector("#baz-confirm").onclick = async () => {
const btn = modal.querySelector("#baz-confirm");
btn.disabled = true; btn.textContent = "…";
try {
const res = await fetch("/api/bazaar/buy", {
method:"POST", headers:{"Content-Type":"application/json"},
body: JSON.stringify({ card_id: card.id }),
});
const data = await res.json();
if (!res.ok) { btn.textContent = data.error||"Fehler"; setTimeout(()=>modal.remove(),2000); return; }
baz_wood=data.wood; baz_iron=data.iron; baz_gold=data.gold; baz_gems=data.gems;
updateCurrencyDisplay();
modal.remove();
showToast(`âś… ${card.name} gekauft!`);
await loadShopCards();
} catch { btn.textContent="Fehler"; setTimeout(()=>modal.remove(),2000); }
};
}
function renderPagination(el, totalPages, total) {
if (!el||!totalPages||totalPages<=1) return;
el.innerHTML = `
${Array.from({length:totalPages},(_,i)=>i+1).map(p=>
``
).join("")}
${total} Karten`;
el.querySelector("#baz-prev")?.addEventListener("click",async()=>{if(baz_page>1){baz_page--;await loadShopCards();}});
el.querySelector("#baz-next")?.addEventListener("click",async()=>{if(baz_pagebtn.addEventListener("click",async()=>{baz_page=parseInt(btn.dataset.page);await loadShopCards();}));
}
function showToast(msg) {
const t=document.createElement("div"); t.className="baz-toast"; t.textContent=msg;
document.body.appendChild(t); setTimeout(()=>t.remove(),2800);
}
function closeBazaar() {
document.getElementById("bazaar-popup")?.classList.remove("active");
document.getElementById("qm-overlay")?.classList.remove("active");
}
export function loadBazaar() {
loadCSS();
ensurePopup();
const popup=document.getElementById("bazaar-popup");
const overlay=document.getElementById("qm-overlay");
popup.style.left="50%"; popup.style.top="50%";
popup.style.transform="translate(-50%, -50%) scale(1)";
popup.classList.add("active");
overlay?.classList.add("active");
if (!baz_initialized) { baz_initialized=true; baz_page=1; loadShopCards(); }
}