From 552eba5ba73e33e546b989723e24b8e48c0b693b Mon Sep 17 00:00:00 2001 From: dnviti Date: Tue, 16 Dec 2025 23:10:59 +0100 Subject: [PATCH] feat: Implement game type filter for expansion selection in Cube Manager, adding 'digital' property to Scryfall sets and corresponding UI. --- docs/development/CENTRAL.md | 1 + .../2025-12-16-231000_game_type_filter.md | 15 +++++++ src/client/src/modules/cube/CubeManager.tsx | 45 ++++++++++++++++--- src/client/src/services/ScryfallService.ts | 4 +- 4 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 docs/development/devlog/2025-12-16-231000_game_type_filter.md diff --git a/docs/development/CENTRAL.md b/docs/development/CENTRAL.md index 51c9cc9..cd21ed3 100644 --- a/docs/development/CENTRAL.md +++ b/docs/development/CENTRAL.md @@ -31,3 +31,4 @@ - [Server-Side Caching](./devlog/2025-12-16-235900_server_side_caching.md): Completed. Implemented logic to cache images and metadata on the server upon bulk parsing, and updated client to use local assets. - [Peasant Algorithm Implementation](./devlog/2025-12-16-225700_peasant_algorithm.md): Completed. Implemented Peasant-specific pack generation rules including slot logic for commons, uncommons, lands, and wildcards. - [Multi-Expansion Selection](./devlog/2025-12-16-230500_multi_expansion_selection.md): Completed. Implemented searchable multi-select interface for "From Expansion" pack generation, allowing mixed-set drafts. +- [Game Type Filter](./devlog/2025-12-16-231000_game_type_filter.md): Completed. Added Paper/Digital filter to the expansion selection list. diff --git a/docs/development/devlog/2025-12-16-231000_game_type_filter.md b/docs/development/devlog/2025-12-16-231000_game_type_filter.md new file mode 100644 index 0000000..f45a9d3 --- /dev/null +++ b/docs/development/devlog/2025-12-16-231000_game_type_filter.md @@ -0,0 +1,15 @@ +# Game Type Filter for Expansion Selection + +## Objective +Add a filter to the "From Expansion" set selection to easily distinguish between Paper and Digital (MTGA/MTGO) sets. + +## Implementation Details +1. **ScryfallService Update**: Updated `ScryfallSet` interface to include the `digital` boolean property and mapped it in `fetchSets`. +2. **CubeManager UI**: Added a toggle filter bar above the set list with three options: + * **All**: Shows all sets. + * **Paper**: Shows only sets where `digital` is false. + * **Digital**: Shows only sets where `digital` is true. +3. **Filter Logic**: Integrated the game type filter into the existing search filter logic in `CubeManager`. + +## Status +Completed. Users can now filter the expansion list by game type. diff --git a/src/client/src/modules/cube/CubeManager.tsx b/src/client/src/modules/cube/CubeManager.tsx index f672259..396c6b5 100644 --- a/src/client/src/modules/cube/CubeManager.tsx +++ b/src/client/src/modules/cube/CubeManager.tsx @@ -96,7 +96,9 @@ export const CubeManager: React.FC = ({ packs, setPacks, onGoT const saved = localStorage.getItem('cube_selectedSets'); return saved ? JSON.parse(saved) : []; }); + const [searchTerm, setSearchTerm] = useState(''); + const [gameTypeFilter, setGameTypeFilter] = useState<'all' | 'paper' | 'digital'>('all'); // Filter state const [numBoxes, setNumBoxes] = useState(() => { const saved = localStorage.getItem('cube_numBoxes'); return saved ? parseInt(saved) : 3; @@ -440,14 +442,47 @@ export const CubeManager: React.FC = ({ packs, setPacks, onGoT )} + {/* Game Type Filter */} +
+ + + +
+ {/* List */}
{availableSets - .filter(s => - !searchTerm || - s.name.toLowerCase().includes(searchTerm.toLowerCase()) || - s.code.toLowerCase().includes(searchTerm.toLowerCase()) - ) + .filter(s => { + // Search Filter + const matchesSearch = !searchTerm || + s.name.toLowerCase().includes(searchTerm.toLowerCase()) || + s.code.toLowerCase().includes(searchTerm.toLowerCase()); + + // Game Type Filter + const matchesType = + gameTypeFilter === 'all' ? true : + gameTypeFilter === 'paper' ? !s.digital : + gameTypeFilter === 'digital' ? s.digital : true; + + return matchesSearch && matchesType; + }) .map(s => { const isSelected = selectedSets.includes(s.code); return ( diff --git a/src/client/src/services/ScryfallService.ts b/src/client/src/services/ScryfallService.ts index 6a919ce..4a2bcb0 100644 --- a/src/client/src/services/ScryfallService.ts +++ b/src/client/src/services/ScryfallService.ts @@ -168,7 +168,8 @@ export class ScryfallService { name: s.name, set_type: s.set_type, released_at: s.released_at, - icon_svg_uri: s.icon_svg_uri + icon_svg_uri: s.icon_svg_uri, + digital: s.digital })); } } catch (e) { @@ -226,4 +227,5 @@ export interface ScryfallSet { set_type: string; released_at: string; icon_svg_uri: string; + digital: boolean; }