From f1499046b5661ee94ddb8fb63025e44bd345abf9 Mon Sep 17 00:00:00 2001 From: Refactoring Agent <[email protected]> Date: Sat, 2 May 2026 21:38:54 +0200 Subject: [PATCH] fix: update EquipmentTab to use modular stores, fixing tab crash --- src/components/game/tabs/EquipmentTab.tsx | 83 +++++++++++++++-------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/src/components/game/tabs/EquipmentTab.tsx b/src/components/game/tabs/EquipmentTab.tsx index a7d1469..5853738 100755 --- a/src/components/game/tabs/EquipmentTab.tsx +++ b/src/components/game/tabs/EquipmentTab.tsx @@ -11,18 +11,20 @@ import { } from '@/lib/game/data/equipment'; import { ENCHANTMENT_EFFECTS } from '@/lib/game/data/enchantment-effects'; import { getUnifiedEffects } from '@/lib/game/effects'; -import { fmt } from '@/lib/game/store'; +import { fmt } from '@/lib/game/stores'; import { Button } from '@/components/ui/button'; import { GameCard } from '@/components/ui/game-card'; import { SectionHeader } from '@/components/ui/section-header'; import { StatRow } from '@/components/ui/stat-row'; import { Badge } from '@/components/ui/badge'; -import type { GameStore, EquipmentInstance } from '@/lib/game/types'; +import type { EquipmentInstance } from '@/lib/game/types'; import { EquipmentSlotGrid } from './EquipmentSlotGrid'; import { EquipmentInventory } from './EquipmentInventory'; import { EnchantmentsPanel } from './EnchantmentsPanel'; import { useGameToast } from '@/components/game/GameToast'; import { ConfirmDialog } from '@/components/game/ConfirmDialog'; +import { equipItem, unequipItem, deleteEquipmentInstance } from '@/lib/game/crafting-actions'; +import { useCombatStore } from '@/lib/game/stores'; // Rarity color mappings using design system tokens export const RARITY_BORDER_COLORS: Record = { @@ -33,7 +35,6 @@ export const RARITY_BORDER_COLORS: Record = { legendary: 'border-[var(--mana-light)]', mythic: 'border-[var(--mana-dark)]', }; - export const RARITY_BG_COLORS: Record = { common: 'bg-[var(--bg-sunken)]/30', uncommon: 'bg-[var(--color-success)]/10', @@ -42,7 +43,6 @@ export const RARITY_BG_COLORS: Record = { legendary: 'bg-[var(--mana-light)]/10', mythic: 'bg-[var(--mana-dark)]/10', }; - export const RARITY_TEXT_COLORS: Record = { common: 'text-[var(--text-secondary)]', uncommon: 'text-[var(--color-success)]', @@ -61,7 +61,7 @@ const SLOT_ICONS: Record = { ), offHand: () => ( - + ), head: () => ( @@ -114,44 +114,57 @@ const SLOT_GROUPS: SlotGroup[] = [ { label: 'Accessories', slots: ['accessory1', 'accessory2'] }, ]; -export function EquipmentTab({ store }: { store: GameStore }) { +export function EquipmentTab() { const showToast = useGameToast(); const [selectedSlot, setSelectedSlot] = useState(null); const [deleteConfirm, setDeleteConfirm] = useState<{ instanceId: string; name: string } | null>(null); + // Use modular store directly + const equippedInstances = useCombatStore((s) => s.equippedInstances); + const equipmentInstances = useCombatStore((s) => s.equipmentInstances); + + // Guard against undefined during initialization + if (!equippedInstances || !equipmentInstances) { + return ( +
+ Loading equipment data... +
+ ); + } + // Get unequipped items const equippedIds = useMemo(() => - new Set(Object.values(store.equippedInstances).filter(Boolean)), - [store.equippedInstances] + new Set(Object.values(equippedInstances).filter(Boolean)), + [equippedInstances] ); const unequippedItems = useMemo(() => - Object.values(store.equipmentInstances).filter( + Object.values(equipmentInstances).filter( (inst) => !equippedIds.has(inst.instanceId) ), - [store.equipmentInstances, equippedIds] + [equipmentInstances, equippedIds] ); // Equip an item to a slot const handleEquip = (instanceId: string, slot: EquipmentSlot) => { - const instance = store.equipmentInstances[instanceId]; - store.equipItem(instanceId, slot); + const instance = equipmentInstances[instanceId]; + equipItem(instanceId, slot, useCombatStore.getState, (fn) => useCombatStore.setState(fn)); setSelectedSlot(null); showToast('success', 'Item Equipped', `${instance?.name || 'Item'} equipped to ${SLOT_NAMES[slot]}`); }; // Unequip from a slot const handleUnequip = (slot: EquipmentSlot) => { - const instanceId = store.equippedInstances[slot]; - const instance = instanceId ? store.equipmentInstances[instanceId] : null; - store.unequipItem(slot); + const instanceId = equippedInstances[slot]; + const instance = instanceId ? equipmentInstances[instanceId] : null; + unequipItem(slot, useCombatStore.getState, (fn) => useCombatStore.setState(fn)); showToast('success', 'Item Unequipped', `${instance?.name || 'Item'} removed from ${SLOT_NAMES[slot]}`); }; // Check if a slot is blocked by a 2-handed weapon const isSlotBlocked = (slot: EquipmentSlot): boolean => { - if (slot === 'offHand' && store.equippedInstances.mainHand) { - const mainHandInstance = store.equipmentInstances[store.equippedInstances.mainHand]; + if (slot === 'offHand' && equippedInstances.mainHand) { + const mainHandInstance = equipmentInstances[equippedInstances.mainHand]; if (!mainHandInstance) return false; const mainHandType = EQUIPMENT_TYPES[mainHandInstance.typeId]; return mainHandType?.twoHanded === true; @@ -189,7 +202,7 @@ export function EquipmentTab({ store }: { store: GameStore }) { // Check if an instance is currently equipped const isEquipped = (instanceId: string): boolean => - Object.values(store.equippedInstances).includes(instanceId); + Object.values(equippedInstances).includes(instanceId); // Get all slots an item type can be equipped to const getEquippableSlots = (typeId: string): EquipmentSlot[] => { @@ -208,12 +221,15 @@ export function EquipmentTab({ store }: { store: GameStore }) { const confirmDelete = () => { if (deleteConfirm) { - store.deleteEquipmentInstance(deleteConfirm.instanceId); + deleteEquipmentInstance(deleteConfirm.instanceId, useCombatStore.getState, (fn) => useCombatStore.setState(fn)); showToast('success', 'Item Discarded', `${deleteConfirm.name} has been removed from inventory`); setDeleteConfirm(null); } }; + // Get unified effects for equipment stats + const unifiedEffects = useCombatStore((s) => s.equipmentInstances) ? getUnifiedEffects({ equipmentInstances, equippedInstances }) : null; + return (
{/* Equipment Slots */} @@ -222,17 +238,20 @@ export function EquipmentTab({ store }: { store: GameStore }) { title="Equipped Gear" action={ - {Object.values(store.equippedInstances).filter(Boolean).length} / {EQUIPMENT_SLOTS.length} slots filled + {Object.values(equippedInstances).filter(Boolean).length} / {EQUIPMENT_SLOTS.length} slots filled } /> @@ -247,8 +266,8 @@ export function EquipmentTab({ store }: { store: GameStore }) {
) : (
- {Object.values(store.equipmentInstances).length} + {Object.values(equipmentInstances).length}
Total Items
@@ -282,7 +301,7 @@ export function EquipmentTab({ store }: { store: GameStore }) {
- {Object.values(store.equipmentInstances).reduce( + {Object.values(equipmentInstances).reduce( (sum, inst) => sum + inst.enchantments.length, 0 )} @@ -300,8 +319,9 @@ export function EquipmentTab({ store }: { store: GameStore }) {
{(() => { - const unifiedEffects = getUnifiedEffects(store); - const enchantPower = unifiedEffects.enchantmentPowerMultiplier || 1; + const effects = unifiedEffects; + if (!effects) return null; + const enchantPower = effects.enchantmentPowerMultiplier || 1; return ( <> Active Effects from Equipment:
{(() => { - const effects = store.getEquipmentEffects(); - const effectEntries = Object.entries(effects).filter(([, v]) => v > 0); - + const effects = unifiedEffects; + if (!effects?.equipmentEffects) { + return No active effects; + } + const effectEntries = Object.entries(effects.equipmentEffects).filter(([, v]) => v > 0); + if (effectEntries.length === 0) { return No active effects; } - + return effectEntries.map(([stat, value]) => ( {stat}: +{fmt(value)}