feat: recreate Equipment Tab with equip/unequip gear management
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m19s

This commit is contained in:
2026-05-19 22:04:27 +02:00
parent 1cd612193d
commit dbc1b5e02c
10 changed files with 637 additions and 3 deletions
+95
View File
@@ -0,0 +1,95 @@
'use client';
import { useState, useEffect, useCallback, useMemo } from 'react';
import { useCraftingStore } from '@/lib/game/stores/craftingStore';
import { equipItem, unequipItem, deleteEquipmentInstance } from '@/lib/game/crafting-actions/equipment-actions';
import type { EquipmentSlot } from '@/lib/game/types';
import { DebugName } from '@/components/game/debug/debug-context';
import { EquipmentSlotGrid } from './EquipmentTab/EquipmentSlotGrid';
import { InventoryList } from './EquipmentTab/InventoryList';
import { EquipmentEffectsSummary } from './EquipmentTab/EquipmentEffectsSummary';
export function EquipmentTab() {
const [mounted, setMounted] = useState(false);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const storeEquipItem = useCraftingStore((s) => s.equipItem);
const storeUnequipItem = useCraftingStore((s) => s.unequipItem);
const storeDeleteEquipment = useCraftingStore((s) => s.deleteEquipmentInstance);
useEffect(() => {
setMounted(true);
}, []);
const handleEquip = useCallback(
(instanceId: string, slot: EquipmentSlot) => {
storeEquipItem(instanceId, slot);
},
[storeEquipItem]
);
const handleUnequip = useCallback(
(slot: EquipmentSlot) => {
storeUnequipItem(slot);
},
[storeUnequipItem]
);
const handleDelete = useCallback(
(instanceId: string) => {
storeDeleteEquipment(instanceId);
},
[storeDeleteEquipment]
);
const inventoryItems = useMemo(
() =>
Object.entries(equipmentInstances).filter(
([id]) => !Object.values(equippedInstances).includes(id)
),
[equipmentInstances, equippedInstances]
);
if (!mounted) {
return (
<div className="flex items-center justify-center p-8 text-[var(--text-muted)]">
Loading equipment
</div>
);
}
return (
<DebugName name="EquipmentTab">
<div className="space-y-6">
<div>
<h2 className="text-lg font-semibold text-[var(--text-primary)] mb-3">Equipped Gear</h2>
<EquipmentSlotGrid
equippedInstances={equippedInstances}
equipmentInstances={equipmentInstances}
onUnequip={handleUnequip}
/>
</div>
<EquipmentEffectsSummary
equipmentInstances={equipmentInstances}
equippedInstances={equippedInstances}
/>
<div>
<h2 className="text-lg font-semibold text-[var(--text-primary)] mb-3">
Inventory ({inventoryItems.length})
</h2>
<InventoryList
inventoryItems={inventoryItems}
equippedInstances={equippedInstances}
onEquip={handleEquip}
onDelete={handleDelete}
/>
</div>
</div>
</DebugName>
);
}
EquipmentTab.displayName = 'EquipmentTab';