dzukdu
This commit is contained in:
parent
29e6fd01de
commit
32c9d78250
@ -1,11 +1,11 @@
|
||||
const CARDS_PER_PAGE = 18;
|
||||
|
||||
let currentGroupId = null;
|
||||
let currentPage = 1;
|
||||
let currentDeckId = null;
|
||||
let deckCards = []; // [{card_id, level, amount}]
|
||||
let userCardsCache = []; // aktuelle Seite: [{card_id, level, amount, name, image, attack, defense}]
|
||||
let decks = []; // [{id, name}]
|
||||
let currentGroupId = null;
|
||||
let currentPage = 1;
|
||||
let currentDeckId = null;
|
||||
let deckCards = []; // [{card_id, level, amount}]
|
||||
let userCardsCache = []; // aktuelle Seite: [{card_id, level, amount, name, image, attack, defense}]
|
||||
let decks = []; // [{id, name}]
|
||||
|
||||
/* ══════════════════════════════════════════════
|
||||
INIT
|
||||
@ -460,16 +460,18 @@ function renderTabs(groups) {
|
||||
const container = document.getElementById("kd-tabs");
|
||||
if (!container) return;
|
||||
|
||||
container.innerHTML = groups.map((g, i) => {
|
||||
const color = g.color || "#6b4b2a";
|
||||
return `
|
||||
container.innerHTML = groups
|
||||
.map((g, i) => {
|
||||
const color = g.color || "#6b4b2a";
|
||||
return `
|
||||
<button class="kd-tab ${i === 0 ? "kd-tab-active" : ""}"
|
||||
data-group="${g.id}"
|
||||
style="border-color:${color};${i === 0 ? `background:${color}33;` : ""}">
|
||||
<span class="kd-tab-dot" style="background:${color};"></span>
|
||||
<span>${g.name}</span>
|
||||
</button>`;
|
||||
}).join("");
|
||||
})
|
||||
.join("");
|
||||
|
||||
container.querySelectorAll(".kd-tab").forEach((btn) => {
|
||||
btn.addEventListener("click", async () => {
|
||||
@ -494,7 +496,7 @@ function renderTabs(groups) {
|
||||
totalPages, total }
|
||||
══════════════════════════════════════════════ */
|
||||
async function loadUserCards() {
|
||||
const grid = document.getElementById("kd-grid");
|
||||
const grid = document.getElementById("kd-grid");
|
||||
const pagination = document.getElementById("kd-pagination");
|
||||
if (!grid) return;
|
||||
|
||||
@ -502,7 +504,9 @@ async function loadUserCards() {
|
||||
pagination.innerHTML = "";
|
||||
|
||||
try {
|
||||
const res = await fetch(`/api/user-cards?group_id=${currentGroupId}&page=${currentPage}&limit=${CARDS_PER_PAGE}`);
|
||||
const res = await fetch(
|
||||
`/api/user-cards?group_id=${currentGroupId}&page=${currentPage}&limit=${CARDS_PER_PAGE}`,
|
||||
);
|
||||
if (!res.ok) throw new Error("API Fehler");
|
||||
const data = await res.json();
|
||||
userCardsCache = data.cards || [];
|
||||
@ -532,8 +536,14 @@ async function loadDecks() {
|
||||
function renderDeckSelect() {
|
||||
const sel = document.getElementById("kd-deck-select");
|
||||
if (!sel) return;
|
||||
sel.innerHTML = `<option value="">— Deck wählen —</option>` +
|
||||
decks.map(d => `<option value="${d.id}" ${d.id === currentDeckId ? "selected" : ""}>${d.name}</option>`).join("");
|
||||
sel.innerHTML =
|
||||
`<option value="">— Deck wählen —</option>` +
|
||||
decks
|
||||
.map(
|
||||
(d) =>
|
||||
`<option value="${d.id}" ${d.id === currentDeckId ? "selected" : ""}>${d.name}</option>`,
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
/* ══════════════════════════════════════════════
|
||||
@ -587,7 +597,9 @@ async function addCardToDeck(card) {
|
||||
|
||||
// Level > 5: max. 1 Exemplar im Deck
|
||||
if (card.level > 5) {
|
||||
const already = deckCards.find(c => c.card_id === card.card_id && c.level === card.level);
|
||||
const already = deckCards.find(
|
||||
(c) => c.card_id === card.card_id && c.level === card.level,
|
||||
);
|
||||
if (already) {
|
||||
showToast("Karten ab Level 6 dürfen nur 1x im Deck sein.");
|
||||
return;
|
||||
@ -684,29 +696,33 @@ function renderCollectionGrid(grid, cards) {
|
||||
|
||||
const totalInDeck = deckCards.reduce((s, c) => s + c.amount, 0);
|
||||
|
||||
grid.innerHTML = cards.map(c => {
|
||||
const inDeck = getDeckCount(c.card_id, c.level);
|
||||
const maxed = isMaxedOut(c, inDeck, totalInDeck);
|
||||
return `
|
||||
grid.innerHTML = cards
|
||||
.map((c) => {
|
||||
const inDeck = getDeckCount(c.card_id, c.level);
|
||||
const maxed = isMaxedOut(c, inDeck, totalInDeck);
|
||||
return `
|
||||
<div class="kd-card ${maxed ? "kd-card-maxed" : ""}"
|
||||
data-card-id="${c.card_id}" data-level="${c.level}"
|
||||
title="${c.name} (Level ${c.level})">
|
||||
<div class="kd-card-name">${c.name}</div>
|
||||
<img src="/images/cards/${c.image}" alt="${c.name}"
|
||||
onerror="this.src='/images/avatar_placeholder.svg'">
|
||||
${c.attack != null ? `<span class="kd-stat-atk">${c.attack}</span>` : ""}
|
||||
${c.attack != null ? `<span class="kd-stat-atk">${c.attack}</span>` : ""}
|
||||
${c.defense != null ? `<span class="kd-stat-def">${c.defense}</span>` : ""}
|
||||
<div class="kd-card-footer">
|
||||
<span class="kd-count-owned" title="Besitzt du">${c.amount}×</span>
|
||||
<span class="kd-count-deck" title="Im Deck">🃏 ${inDeck}</span>
|
||||
</div>
|
||||
</div>`;
|
||||
}).join("");
|
||||
})
|
||||
.join("");
|
||||
|
||||
grid.querySelectorAll(".kd-card:not(.kd-card-maxed)").forEach(el => {
|
||||
grid.querySelectorAll(".kd-card:not(.kd-card-maxed)").forEach((el) => {
|
||||
el.addEventListener("click", async () => {
|
||||
const card = cards.find(
|
||||
c => c.card_id === parseInt(el.dataset.cardId) && c.level === parseInt(el.dataset.level)
|
||||
(c) =>
|
||||
c.card_id === parseInt(el.dataset.cardId) &&
|
||||
c.level === parseInt(el.dataset.level),
|
||||
);
|
||||
if (card) await addCardToDeck(card);
|
||||
});
|
||||
@ -722,10 +738,13 @@ function renderDeckGrid(grid, cards) {
|
||||
return;
|
||||
}
|
||||
// Owned-Anzahl aus userCardsCache auslesen
|
||||
grid.innerHTML = cards.map(c => {
|
||||
const ownedEntry = userCardsCache.find(u => u.card_id === c.card_id && u.level === c.level);
|
||||
const ownedAmt = ownedEntry ? ownedEntry.amount : "?";
|
||||
return `
|
||||
grid.innerHTML = cards
|
||||
.map((c) => {
|
||||
const ownedEntry = userCardsCache.find(
|
||||
(u) => u.card_id === c.card_id && u.level === c.level,
|
||||
);
|
||||
const ownedAmt = ownedEntry ? ownedEntry.amount : "?";
|
||||
return `
|
||||
<div class="kd-deck-card" data-card-id="${c.card_id}" data-level="${c.level}" title="Klicken zum Entfernen: ${c.name}">
|
||||
<img src="/images/cards/${c.image}" alt="${c.name}"
|
||||
onerror="this.src='/images/avatar_placeholder.svg'">
|
||||
@ -733,16 +752,18 @@ function renderDeckGrid(grid, cards) {
|
||||
<span class="kd-deck-card-name">${c.name}</span>
|
||||
</div>
|
||||
<div class="kd-deck-card-footer-counts">
|
||||
<span class="kd-deck-count-owned" title="Besessen">${ownedAmt}×</span>
|
||||
<span class="kd-deck-count-indeck" title="Im Deck">🃏 ${c.amount}</span>
|
||||
</div>
|
||||
</div>`;
|
||||
}).join("");
|
||||
})
|
||||
.join("");
|
||||
|
||||
grid.querySelectorAll(".kd-deck-card").forEach(el => {
|
||||
grid.querySelectorAll(".kd-deck-card").forEach((el) => {
|
||||
el.addEventListener("click", async () => {
|
||||
const card = cards.find(
|
||||
c => c.card_id === parseInt(el.dataset.cardId) && c.level === parseInt(el.dataset.level)
|
||||
(c) =>
|
||||
c.card_id === parseInt(el.dataset.cardId) &&
|
||||
c.level === parseInt(el.dataset.level),
|
||||
);
|
||||
if (card) await removeCardFromDeck(card);
|
||||
});
|
||||
@ -756,19 +777,29 @@ function renderPagination(pagination, totalPages, total) {
|
||||
if (!totalPages || totalPages <= 1) return;
|
||||
pagination.innerHTML = `
|
||||
<button class="kd-page-btn" id="kd-prev" ${currentPage === 1 ? "disabled" : ""}>◀</button>
|
||||
${Array.from({ length: totalPages }, (_, i) => i + 1).map(p => `
|
||||
${Array.from({ length: totalPages }, (_, i) => i + 1)
|
||||
.map(
|
||||
(p) => `
|
||||
<button class="kd-page-btn ${p === currentPage ? "kd-page-active" : ""}" data-page="${p}">${p}</button>
|
||||
`).join("")}
|
||||
`,
|
||||
)
|
||||
.join("")}
|
||||
<button class="kd-page-btn" id="kd-next" ${currentPage === totalPages ? "disabled" : ""}>▶</button>
|
||||
<span class="kd-page-info">${total} Karten</span>`;
|
||||
|
||||
pagination.querySelector("#kd-prev")?.addEventListener("click", async () => {
|
||||
if (currentPage > 1) { currentPage--; await loadUserCards(); }
|
||||
if (currentPage > 1) {
|
||||
currentPage--;
|
||||
await loadUserCards();
|
||||
}
|
||||
});
|
||||
pagination.querySelector("#kd-next")?.addEventListener("click", async () => {
|
||||
if (currentPage < totalPages) { currentPage++; await loadUserCards(); }
|
||||
if (currentPage < totalPages) {
|
||||
currentPage++;
|
||||
await loadUserCards();
|
||||
}
|
||||
});
|
||||
pagination.querySelectorAll("[data-page]").forEach(btn => {
|
||||
pagination.querySelectorAll("[data-page]").forEach((btn) => {
|
||||
btn.addEventListener("click", async () => {
|
||||
currentPage = parseInt(btn.dataset.page);
|
||||
await loadUserCards();
|
||||
@ -832,7 +863,10 @@ function showNewDeckModal() {
|
||||
modal.querySelector("#kd-modal-cancel").onclick = () => modal.remove();
|
||||
modal.querySelector("#kd-modal-confirm").onclick = async () => {
|
||||
const name = input.value.trim();
|
||||
if (!name) { input.focus(); return; }
|
||||
if (!name) {
|
||||
input.focus();
|
||||
return;
|
||||
}
|
||||
modal.remove();
|
||||
await createDeck(name);
|
||||
};
|
||||
@ -851,14 +885,16 @@ function showNewDeckModal() {
|
||||
HELPERS
|
||||
══════════════════════════════════════════════ */
|
||||
function getDeckCount(cardId, level) {
|
||||
const entry = deckCards.find(c => c.card_id === cardId && c.level === level);
|
||||
const entry = deckCards.find(
|
||||
(c) => c.card_id === cardId && c.level === level,
|
||||
);
|
||||
return entry ? entry.amount : 0;
|
||||
}
|
||||
|
||||
function isMaxedOut(card, inDeck, totalInDeck) {
|
||||
if (!currentDeckId) return false;
|
||||
if (totalInDeck >= 30) return true;
|
||||
if (inDeck >= card.amount) return true; // mehr als besessen
|
||||
if (inDeck >= card.amount) return true; // mehr als besessen
|
||||
if (card.level > 5 && inDeck >= 1) return true; // Level > 5: nur 1x
|
||||
return false;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user