From c6234d953d025700bad31f728fc040ba80aecee5 Mon Sep 17 00:00:00 2001 From: cay Date: Sat, 4 Apr 2026 10:28:05 +0100 Subject: [PATCH] hj,c --- public/js/quickmenu/carddeck.js | 73 +++++++++++++++++---------------- routes/carddeck.js | 46 +++++++++++---------- 2 files changed, 62 insertions(+), 57 deletions(-) diff --git a/public/js/quickmenu/carddeck.js b/public/js/quickmenu/carddeck.js index 4984b9b..2cb4a87 100644 --- a/public/js/quickmenu/carddeck.js +++ b/public/js/quickmenu/carddeck.js @@ -3,8 +3,8 @@ 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 deckCards = []; // [{card_id, amount}] +let userCardsCache = []; // aktuelle Seite: [{card_id, amount, name, image, rarity, attack, defense}] let decks = []; // [{id, name}] @@ -19,10 +19,12 @@ const RARITY_CRYSTALS = { "7": "pinker-cristal.png", }; -function rarityImg(rarity, size = 16) { +function rarityImgs(rarity, size = 14) { const file = RARITY_CRYSTALS[String(rarity)]; if (!file) return ""; - return `Stufe ${rarity}`; + const count = parseInt(rarity) || 0; + const img = `Stufe ${rarity}`; + return img.repeat(count); } /* ══════════════════════════════════════════════ @@ -415,14 +417,19 @@ function renderShell() { } .kd-deck-count-indeck { font-family: "Cinzel", serif; font-size: 13px; color: #88cc44; font-weight: bold; } - /* ── Rarity Kristall ────────────────────── */ + /* ── Rarity Kristalle ───────────────────── */ .kd-rarity { - position: absolute; - top: 3px; - right: 4px; - z-index: 5; - pointer-events: none; - line-height: 0; + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + gap: 1px; + padding: 3px 4px; + background: rgba(0,0,0,0.82); + border-top: 1px solid #3a2810; + flex-shrink: 0; + min-height: 20px; + border-radius: 0 0 6px 6px; } /* ── Empty / Loading States ──────────────── */ @@ -612,18 +619,18 @@ async function addCardToDeck(card) { return; } - // 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); + // Rarity > 5: max. 1 Exemplar im Deck + if (parseInt(card.rarity) > 5) { + const already = deckCards.find(c => c.card_id === card.card_id); if (already) { - showToast("Karten ab Level 6 dürfen nur 1x im Deck sein."); + showToast("Karten ab Rarity 6 dürfen nur 1x im Deck sein."); return; } } // Nicht mehr als vorhanden besitzt const owned = card.amount; - const inDeck = getDeckCount(card.card_id, card.level); + const inDeck = getDeckCount(card.card_id); if (inDeck >= owned) { showToast("Du hast keine weiteren Exemplare dieser Karte."); return; @@ -633,7 +640,7 @@ async function addCardToDeck(card) { const res = await fetch(`/api/decks/${currentDeckId}/cards`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ card_id: card.card_id, level: card.level }), + body: JSON.stringify({ card_id: card.card_id }), }); if (!res.ok) { const err = await res.json(); @@ -655,7 +662,7 @@ async function removeCardFromDeck(card) { const res = await fetch(`/api/decks/${currentDeckId}/cards`, { method: "DELETE", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ card_id: card.card_id, level: card.level }), + body: JSON.stringify({ card_id: card.card_id }), }); if (!res.ok) { const err = await res.json(); @@ -712,14 +719,13 @@ 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 inDeck = getDeckCount(c.card_id); const maxed = isMaxedOut(c, inDeck, totalInDeck); return `
+ data-card-id="${c.card_id}" + title="${c.name}">
${c.name}
- ${c.rarity ? `${rarityImg(c.rarity, 15)}` : ""} ${c.name} ${c.attack != null ? `${c.attack}` : ""} @@ -728,14 +734,13 @@ function renderCollectionGrid(grid, cards) { ${c.amount}× 🃏 ${inDeck}
+ ${c.rarity ? `
${rarityImgs(c.rarity, 13)}
` : ""} `; }).join(""); 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) - ); + const card = cards.find(c => c.card_id === parseInt(el.dataset.cardId)); if (card) await addCardToDeck(card); }); }); @@ -751,11 +756,10 @@ function renderDeckGrid(grid, cards) { } // 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 ownedEntry = userCardsCache.find(u => u.card_id === c.card_id); const ownedAmt = ownedEntry ? ownedEntry.amount : "?"; return ` -
- ${c.rarity ? `${rarityImg(c.rarity, 18)}` : ""} +
${c.name} `; }).join(""); 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) - ); + const card = cards.find(c => c.card_id === parseInt(el.dataset.cardId)); if (card) await removeCardFromDeck(card); }); }); @@ -878,16 +881,16 @@ function showNewDeckModal() { /* ══════════════════════════════════════════════ HELPERS ══════════════════════════════════════════════ */ -function getDeckCount(cardId, level) { - const entry = deckCards.find(c => c.card_id === cardId && c.level === level); +function getDeckCount(cardId) { + const entry = deckCards.find(c => c.card_id === cardId); 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 (card.level > 5 && inDeck >= 1) return true; // Level > 5: nur 1x + if (inDeck >= card.amount) return true; // mehr als besessen + if (parseInt(card.rarity) > 5 && inDeck >= 1) return true; // Rarity > 5: nur 1x return false; } diff --git a/routes/carddeck.js b/routes/carddeck.js index bbd3087..5de5609 100644 --- a/routes/carddeck.js +++ b/routes/carddeck.js @@ -73,7 +73,6 @@ router.get("/user-cards", async (req, res) => { const [cards] = await db.query( `SELECT uc.card_id, - uc.level, uc.amount, c.name, c.image, @@ -86,9 +85,9 @@ router.get("/user-cards", async (req, res) => { FROM user_cards uc JOIN cards c ON c.id = uc.card_id JOIN card_groups cg ON cg.id = c.group_id - LEFT JOIN card_levels cl ON cl.card_id = uc.card_id AND cl.level = uc.level + LEFT JOIN card_levels cl ON cl.card_id = uc.card_id AND cl.level = 1 WHERE uc.user_id = ? AND c.group_id = ? - ORDER BY c.id, uc.level + ORDER BY c.id LIMIT ? OFFSET ?`, [userId, group_id, parseInt(limit), parseInt(offset)] ); @@ -186,7 +185,6 @@ router.get("/decks/:id/cards", async (req, res) => { const [cards] = await db.query( `SELECT dc.card_id, - dc.level, dc.amount, c.name, c.image, @@ -195,9 +193,9 @@ router.get("/decks/:id/cards", async (req, res) => { cl.defense FROM deck_cards dc JOIN cards c ON c.id = dc.card_id - LEFT JOIN card_levels cl ON cl.card_id = dc.card_id AND cl.level = dc.level + LEFT JOIN card_levels cl ON cl.card_id = dc.card_id AND cl.level = 1 WHERE dc.deck_id = ? - ORDER BY c.name, dc.level`, + ORDER BY c.name`, [deckId] ); res.json(cards); @@ -215,7 +213,7 @@ router.get("/decks/:id/cards", async (req, res) => { router.post("/decks/:id/cards", async (req, res) => { const userId = req.session.user.id; const deckId = req.params.id; - const { card_id, level = 1 } = req.body; + const { card_id } = req.body; if (!card_id) return res.status(400).json({ error: "card_id fehlt." }); @@ -227,10 +225,10 @@ router.post("/decks/:id/cards", async (req, res) => { ); if (!deck) return res.status(404).json({ error: "Deck nicht gefunden." }); - // Besitzt der Spieler diese Karte mit diesem Level? + // Besitzt der Spieler diese Karte? const [[owned]] = await db.query( - "SELECT amount FROM user_cards WHERE user_id = ? AND card_id = ? AND level = ?", - [userId, card_id, level] + "SELECT amount FROM user_cards WHERE user_id = ? AND card_id = ?", + [userId, card_id] ); if (!owned) return res.status(400).json({ error: "Du besitzt diese Karte nicht." }); @@ -243,14 +241,18 @@ router.post("/decks/:id/cards", async (req, res) => { return res.status(400).json({ error: "Deck ist voll (max. 30 Karten)." }); } - // Level > 5: max. 1× im Deck + // Rarity > 5: max. 1× im Deck + const [[cardInfo]] = await db.query( + "SELECT rarity FROM cards WHERE id = ?", + [card_id] + ); const [[existing]] = await db.query( - "SELECT amount FROM deck_cards WHERE deck_id = ? AND card_id = ? AND level = ?", - [deckId, card_id, level] + "SELECT amount FROM deck_cards WHERE deck_id = ? AND card_id = ?", + [deckId, card_id] ); - if (level > 5 && existing) { - return res.status(400).json({ error: "Karten ab Level 6 dürfen nur einmal im Deck sein." }); + if (parseInt(cardInfo?.rarity) > 5 && existing) { + return res.status(400).json({ error: "Karten ab Rarity 6 dürfen nur einmal im Deck sein." }); } // Nicht mehr einfügen als besessen @@ -262,13 +264,13 @@ router.post("/decks/:id/cards", async (req, res) => { // Einfügen oder erhöhen if (existing) { await db.query( - "UPDATE deck_cards SET amount = amount + 1 WHERE deck_id = ? AND card_id = ? AND level = ?", - [deckId, card_id, level] + "UPDATE deck_cards SET amount = amount + 1 WHERE deck_id = ? AND card_id = ?", + [deckId, card_id] ); } else { await db.query( - "INSERT INTO deck_cards (deck_id, card_id, level, amount) VALUES (?, ?, ?, 1)", - [deckId, card_id, level] + "INSERT INTO deck_cards (deck_id, card_id, amount) VALUES (?, ?, 1)", + [deckId, card_id] ); } @@ -291,7 +293,7 @@ router.post("/decks/:id/cards", async (req, res) => { router.delete("/decks/:id/cards", async (req, res) => { const userId = req.session.user.id; const deckId = req.params.id; - const { card_id, level = 1 } = req.body; + const { card_id } = req.body; if (!card_id) return res.status(400).json({ error: "card_id fehlt." }); @@ -304,8 +306,8 @@ router.delete("/decks/:id/cards", async (req, res) => { if (!deck) return res.status(404).json({ error: "Deck nicht gefunden." }); const [[entry]] = await db.query( - "SELECT id, amount FROM deck_cards WHERE deck_id = ? AND card_id = ? AND level = ?", - [deckId, card_id, level] + "SELECT id, amount FROM deck_cards WHERE deck_id = ? AND card_id = ?", + [deckId, card_id] ); if (!entry) return res.status(404).json({ error: "Karte nicht im Deck." });