From 6e23e32bb093efacd5fcf02123c1bcb993e51f78 Mon Sep 17 00:00:00 2001 From: Nikolaj Date: Thu, 26 Mar 2026 13:29:43 +0100 Subject: [PATCH] :goat: --- backend/card.py | 1 + backend/main.py | 8 ++++++++ frontend/src/lib/CardSelector.svelte | 19 +++++++++++++++++++ frontend/src/routes/shards/+page.svelte | 6 +++++- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/backend/card.py b/backend/card.py index c1bbc2c..93af87d 100644 --- a/backend/card.py +++ b/backend/card.py @@ -243,6 +243,7 @@ WIKIDATA_INSTANCE_TYPE_MAP = { "Q24034552": CardType.science_thing, # mathematical concept "Q12089225": CardType.science_thing, # mineral species "Q55640599": CardType.science_thing, # group of chemical entities + "Q17339814": CardType.science_thing, # group or class of chemical substances "Q119459661": CardType.science_thing, # scientific activity "Q113145171": CardType.science_thing, # type of chemical entity diff --git a/backend/main.py b/backend/main.py index 6b0da49..36f8a1a 100644 --- a/backend/main.py +++ b/backend/main.py @@ -163,6 +163,14 @@ def get_cards(user: UserModel = Depends(get_current_user), db: Session = Depends for card in cards ] +@app.get("/cards/in-decks") +def get_cards_in_decks(user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)): + deck_ids = [d.id for d in db.query(DeckModel).filter(DeckModel.user_id == user.id, DeckModel.deleted == False).all()] + if not deck_ids: + return [] + card_ids = db.query(DeckCardModel.card_id).filter(DeckCardModel.deck_id.in_(deck_ids)).distinct().all() + return [str(row.card_id) for row in card_ids] + @app.post("/open_pack") @limiter.limit("10/minute") async def open_pack(request: Request, user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)): diff --git a/frontend/src/lib/CardSelector.svelte b/frontend/src/lib/CardSelector.svelte index e5cce3c..9dabd14 100644 --- a/frontend/src/lib/CardSelector.svelte +++ b/frontend/src/lib/CardSelector.svelte @@ -8,6 +8,7 @@ let { allCards = [], selectedIds = $bindable(new Set()), + inDeckIds = new Set(), onclose = null, costLimit = null, // if set, prevents selecting cards that would exceed it showFooter = true, // set false to hide the Done button (e.g. inline deck builder) @@ -185,6 +186,9 @@ {#if selectedIds.has(card.id)}
{/if} + {#if inDeckIds.has(card.id)} +
+ {/if} {/each} @@ -410,6 +414,21 @@ z-index: 10; } + .in-deck-badge { + position: absolute; + top: 6px; + right: 6px; + background: rgba(13, 8, 2, 0.75); + color: #7ecfcf; + font-size: 16px; + line-height: 1; + padding: 3px 5px; + border-radius: 6px; + border: 1px solid rgba(126, 207, 207, 0.5); + pointer-events: none; + z-index: 10; + } + .status { font-family: 'Crimson Text', serif; font-size: 16px; diff --git a/frontend/src/routes/shards/+page.svelte b/frontend/src/routes/shards/+page.svelte index 20c2898..6b59c48 100644 --- a/frontend/src/routes/shards/+page.svelte +++ b/frontend/src/routes/shards/+page.svelte @@ -11,20 +11,23 @@ let selectorOpen = $state(false); let shattering = $state(false); let result = $state(null); // { gained, shards } + let inDeckIds = $state(new Set()); const selectedCards = $derived(allCards.filter(c => selectedIds.has(c.id))); const totalYield = $derived(selectedCards.reduce((sum, c) => sum + c.cost, 0)); onMount(async () => { if (!localStorage.getItem('token')) { goto('/auth'); return; } - const [cardsRes, profileRes] = await Promise.all([ + const [cardsRes, profileRes, inDecksRes] = await Promise.all([ apiFetch(`${API_URL}/cards`), apiFetch(`${API_URL}/profile`), + apiFetch(`${API_URL}/cards/in-decks`), ]); if (cardsRes.status === 401) { goto('/auth'); return; } allCards = await cardsRes.json(); const profile = await profileRes.json(); shards = profile.shards; + if (inDecksRes.ok) inDeckIds = new Set(await inDecksRes.json()); }); async function shatter() { @@ -95,6 +98,7 @@ { selectorOpen = false; }} />