feat: recreate Equipment Tab with equip/unequip gear management
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m19s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m19s
This commit is contained in:
@@ -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';
|
||||
Reference in New Issue
Block a user