import React, { useState, useEffect } from 'react'; import { Inventory, InvItemInteraction, Pet } from '../../types/Pet'; import { putPetItemInteract, getItemIcon, getItemInfo } from '../../services/api/api'; import { Loader2 } from 'lucide-react'; import { GameItem, ItemRarity } from '../../types/GameItem'; interface InventoryModalProps { inventory: Inventory; petId: string; onClose: () => void; onPetUpdate: (updatedPet: Pet) => void; } export default function InventoryModal({ inventory, petId, onClose, onPetUpdate }: InventoryModalProps) { const capacity = inventory.capacity; const items = inventory.items; const gridSlots = Array.from({ length: capacity }, (_, i) => items[i]); const [selectedItemIndex, setSelectedItemIndex] = useState(null); const [itemIcons, setItemIcons] = useState>(new Map()); const [loadingIcons, setLoadingIcons] = useState>(new Set()); const [selectedItemDetails, setSelectedItemDetails] = useState(null); const [loadingDetails, setLoadingDetails] = useState(false); const rarityColors = { [ItemRarity.Common]: 'text-gray-200', [ItemRarity.Uncommon]: 'text-green-400', [ItemRarity.Rare]: 'text-blue-400', [ItemRarity.Legendary]: 'text-purple-400' }; useEffect(() => { const fetchItemIcons = async () => { const newIcons = new Map(); const loadingItems = new Set(); for (const itemId of items) { if (itemId !== undefined && !itemIcons.has(itemId)) { loadingItems.add(itemId); } } setLoadingIcons(loadingItems); for (const itemId of loadingItems) { if (itemId !== undefined && !itemIcons.has(itemId)) { try { const blob = await getItemIcon(itemId); const imageUrl = URL.createObjectURL(blob); newIcons.set(itemId, imageUrl); } catch (error) { console.error(`Failed to load icon for item ${itemId}:`, error); } finally { loadingItems.delete(itemId); setLoadingIcons(new Set(loadingItems)); } } } setItemIcons(new Map([...itemIcons, ...newIcons])); }; fetchItemIcons(); return () => { // Cleanup object URLs on unmount itemIcons.forEach(url => URL.revokeObjectURL(url)); }; }, [items]); const handleItemClick = async (index: number) => { if (selectedItemIndex === index || gridSlots[index] === undefined) { setSelectedItemIndex(null); setSelectedItemDetails(null); return; } setSelectedItemIndex(index); const itemId = gridSlots[index]; if (itemId !== undefined) { setLoadingDetails(true); try { const details = await getItemInfo(itemId); setSelectedItemDetails(details); } catch (error) { console.error('Failed to load item details:', error); } finally { setLoadingDetails(false); } } }; const handleInteraction = async (interaction: InvItemInteraction) => { if (selectedItemIndex === null || gridSlots[selectedItemIndex] === undefined) return; try { const updatedPet = await putPetItemInteract(petId, gridSlots[selectedItemIndex], interaction); onPetUpdate(updatedPet); } catch (error) { console.error('Item interaction failed:', error); } }; return (

Inventory

{gridSlots.map((itemId, index) => (
handleItemClick(index)} className={`border rounded p-2 flex items-center justify-center h-24 w-24 ${itemId !== undefined ? 'bg-gray-700 cursor-pointer' : 'bg-gray-800 text-gray-500'} ${selectedItemIndex === index ? 'border-blue-500 animate-pulse' : 'border-gray-600'}`} > {itemId !== undefined ? ( loadingIcons.has(itemId) ? ( ) : ( {`Item ) ) : ( Empty )}
))}
{selectedItemIndex !== null && (
{loadingDetails ? (
) : selectedItemDetails ? (

{selectedItemDetails.name}

{selectedItemDetails.rarity} {selectedItemDetails.type}
{selectedItemDetails.description.split(';').map((line, index) => (

{line.trim()}

))}
) : null}
)}
); }