fix: update SpellsTab to use modular stores, fixing tab crash
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m42s

This commit is contained in:
Refactoring Agent
2026-05-02 21:31:14 +02:00
parent 40d310b55a
commit 129f7876c1
+32 -22
View File
@@ -1,34 +1,44 @@
'use client'; 'use client';
import { useCombatStore, useManaStore, useSkillStore } from '@/lib/game/stores';
import { GameCard, ElementBadge } from '@/components/ui'; import { GameCard, ElementBadge } from '@/components/ui';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { ELEMENTS, SPELLS_DEF } from '@/lib/game/constants'; import { ELEMENTS, SPELLS_DEF } from '@/lib/game/constants';
import { ENCHANTMENT_EFFECTS } from '@/lib/game/data/enchantment-effects'; import { ENCHANTMENT_EFFECTS } from '@/lib/game/data/enchantment-effects';
import { canAffordSpellCost } from '@/lib/game/store'; import { canAffordSpellCost } from '@/lib/game/stores';
import { formatSpellCost, getSpellCostColor } from '@/lib/game/formatting'; import { formatSpellCost, getSpellCostColor } from '@/lib/game/formatting';
interface SpellsTabProps { export function SpellsTab() {
store: { // Use modular stores directly
spells: Record<string, { learned: boolean; level: number; studyProgress: number }>; const spells = useCombatStore((s) => s.spells);
equippedInstances: Record<string, string | null>; const activeSpell = useCombatStore((s) => s.activeSpell);
equipmentInstances: Record<string, { instanceId: string; name: string; enchantments: { effectId: string; stacks: number }[] }>; const setSpell = useCombatStore((s) => s.setSpell);
activeSpell: string;
rawMana: number; const equippedInstances = useCombatStore((s) => s.equippedInstances);
elements: Record<string, { current: number; max: number; unlocked: boolean }>; const equipmentInstances = useCombatStore((s) => s.equipmentInstances);
signedPacts: number[];
unlockedEffects: string[]; const rawMana = useManaStore((s) => s.rawMana);
setSpell: (spellId: string) => void; const elements = useManaStore((s) => s.elements);
};
} const signedPacts = useSkillStore((s) => s.signedPacts);
const unlockedEffects = useSkillStore((s) => s.unlockedEffects);
export function SpellsTab({ store }: SpellsTabProps) {
// Get spells from equipment // Get spells from equipment
const equipmentSpellIds: string[] = []; const equipmentSpellIds: string[] = [];
const spellSources: Record<string, string[]> = {}; const spellSources: Record<string, string[]> = {};
for (const instanceId of Object.values(store.equippedInstances)) { // Guard against undefined stores during initialization
if (!equippedInstances || !equipmentInstances) {
return (
<div className="p-4 text-center text-[var(--text-muted)]">
Loading spell data...
</div>
);
}
for (const instanceId of Object.values(equippedInstances)) {
if (!instanceId) continue; if (!instanceId) continue;
const instance = store.equipmentInstances[instanceId]; const instance = equipmentInstances[instanceId];
if (!instance) continue; if (!instance) continue;
for (const ench of instance.enchantments) { for (const ench of instance.enchantments) {
@@ -49,10 +59,10 @@ export function SpellsTab({ store }: SpellsTabProps) {
const canCastSpell = (spellId: string): boolean => { const canCastSpell = (spellId: string): boolean => {
const spell = SPELLS_DEF[spellId]; const spell = SPELLS_DEF[spellId];
if (!spell || !spell.cost) return false; if (!spell || !spell.cost) return false;
return canAffordSpellCost(spell.cost, store.rawMana, store.elements); return canAffordSpellCost(spell.cost, rawMana, elements);
}; };
const hasPactSpells = store.signedPacts.length > 0; const hasPactSpells = signedPacts && signedPacts.length > 0;
return ( return (
<div className="space-y-6"> <div className="space-y-6">
@@ -72,7 +82,7 @@ export function SpellsTab({ store }: SpellsTabProps) {
const def = SPELLS_DEF[id]; const def = SPELLS_DEF[id];
if (!def) return null; if (!def) return null;
const isActive = store.activeSpell === id; const isActive = activeSpell === id;
const canCast = canCastSpell(id); const canCast = canCastSpell(id);
const elemDef = def.elem === 'raw' ? null : ELEMENTS[def.elem]; const elemDef = def.elem === 'raw' ? null : ELEMENTS[def.elem];
const sources = spellSources[id] || []; const sources = spellSources[id] || [];
@@ -116,7 +126,7 @@ export function SpellsTab({ store }: SpellsTabProps) {
) : ( ) : (
<button <button
className="px-3 py-1 text-xs border border-[var(--border-default)] rounded hover:border-[var(--border-focus)] transition-colors" className="px-3 py-1 text-xs border border-[var(--border-default)] rounded hover:border-[var(--border-focus)] transition-colors"
onClick={() => store.setSpell(id)} onClick={() => setSpell(id)}
> >
Set Active Set Active
</button> </button>
@@ -169,7 +179,7 @@ export function SpellsTab({ store }: SpellsTabProps) {
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{Object.entries(SPELLS_DEF).map(([id, def]) => { {Object.entries(SPELLS_DEF).map(([id, def]) => {
const elemDef = def.elem === 'raw' ? null : ELEMENTS[def.elem]; const elemDef = def.elem === 'raw' ? null : ELEMENTS[def.elem];
const isUnlocked = store.unlockedEffects?.includes(`spell_${id}`); const isUnlocked = unlockedEffects?.includes(`spell_${id}`);
return ( return (
<GameCard <GameCard