diff --git a/src/commands/buddy/BuddyPanel.tsx b/src/commands/buddy/BuddyPanel.tsx index 3438215bf..952335dcf 100644 --- a/src/commands/buddy/BuddyPanel.tsx +++ b/src/commands/buddy/BuddyPanel.tsx @@ -4,7 +4,6 @@ import { Box, Text, Pane, Tab, Tabs, useInput, type Color } from '@anthropic/ink import { useSetAppState } from '../../state/AppState.js'; import { useKeybinding } from '../../keybindings/useKeybinding.js'; import { useExitOnCtrlCDWithKeybindings } from '../../hooks/useExitOnCtrlCDWithKeybindings.js'; -import { Select } from '../../components/CustomSelect/select.js'; import { STAT_NAMES, STAT_LABELS, @@ -365,10 +364,24 @@ function CreatureDetail({ // ─── Dex Tab ────────────────────────────────────────── +const BAR_WIDTH = 30 + +const GEN_RANGES = [ + { label: 'Gen I', start: 1, end: 151 }, + { label: 'Gen II', start: 152, end: 251 }, + { label: 'Gen III', start: 252, end: 386 }, + { label: 'Gen IV', start: 387, end: 493 }, + { label: 'Gen V', start: 494, end: 649 }, + { label: 'Gen VI', start: 650, end: 721 }, + { label: 'Gen VII', start: 722, end: 809 }, + { label: 'Gen VIII',start: 810, end: 905 }, + { label: 'Gen IX', start: 906, end: 1025 }, +] + function DexTab({ buddyData, - isActive, - onUpdate, + isActive: _isActive, + onUpdate: _onUpdate, onClose, }: { buddyData: BuddyData; @@ -376,229 +389,94 @@ function DexTab({ onUpdate: (data: BuddyData) => void; onClose: () => void; }) { - const dexMap = new Map(buddyData.dex.map(d => [d.speciesId, d])); const collected = buddyData.dex.length; const total = ALL_SPECIES_IDS.length; - const flatSpecies = groupByChain().flat(); + const percent = total > 0 ? collected / total : 0; const partySet = new Set(buddyData.party.filter((id): id is string => id !== null)); - const [focusedId, setFocusedId] = useState(flatSpecies[0]); - const [statusMsg, setStatusMsg] = useState(null); + // Per-gen stats + const genStats = GEN_RANGES.map(g => { + const genSpecies = ALL_SPECIES_IDS.filter(id => { + const n = getSpeciesData(id).dexNumber + return n >= g.start && n <= g.end + }) + const collectedNums = new Set(buddyData.dex.map(e => getSpeciesData(e.speciesId).dexNumber)) + const genCollected = genSpecies.filter(id => collectedNums.has(getSpeciesData(id).dexNumber)).length + return { ...g, total: genSpecies.length, collected: genCollected } + }) - // Build options for the Select component - const options = flatSpecies.map(speciesId => { - const species = getSpeciesData(speciesId); - const entry = dexMap.get(speciesId); - const discovered = !!entry; - const inParty = buddyData.creatures.some(c => partySet.has(c.id) && c.speciesId === speciesId); + // Discover party species detail for display + const discovered = buddyData.dex + .sort((a, b) => getSpeciesData(a.speciesId).dexNumber - getSpeciesData(b.speciesId).dexNumber) + .slice(0, 15) - return { - label: ( - - #{String(species.dexNumber).padStart(3, '0')} - - {discovered ? (species.names.zh ?? species.name) : '???'} - - {inParty && } - - ), - value: speciesId, - disabled: false, - }; - }); - - // Right panel data - const focusedSpecies = getSpeciesData(focusedId); - const focusedEntry = dexMap.get(focusedId); - const focusedDiscovered = !!focusedEntry; - const focusedOwned = buddyData.creatures.find(c => c.speciesId === focusedId); - const focusedInParty = focusedOwned ? partySet.has(focusedOwned.id) : false; - - const spriteLines = focusedDiscovered - ? (loadSprite(focusedId)?.lines ?? getFallbackSprite(focusedId)) - : null; - - const maxBase = 130; - - const handleAddToParty = (speciesId: SpeciesId) => { - const creature = buddyData.creatures.find(c => c.speciesId === speciesId); - if (!creature) return; - - // Already in party? - if (partySet.has(creature.id)) { - setStatusMsg('Already in party!'); - return; - } - - const result = addToParty(buddyData, creature.id); - if (result.added) { - onUpdate(result.data); - setStatusMsg(`Added ${getCreatureName(creature)} to party!`); - } else { - setStatusMsg('Party is full! Remove a member first.'); - } - }; + void onClose; // used by parent return ( - {/* Header */} + {/* Header with percentage */} Pokédex {collected} - /{total} - - {'█'.repeat(collected)} - {'░'.repeat(total - collected)} - {Math.floor((collected / total) * 100)}% + /{total} + {(percent * 100).toFixed(1)}% - {/* Two-column: Select list | detail */} - - {/* ── Left: Select list ── */} - -