feat: integrate Firebase for authentication and data management, add GameItem type, and enhance UI with tooltips
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Inventory, InvItemInteraction, Pet } from '../../types/Pet';
|
||||
import { putPetItemInteract, getItemIcon } from '../../services/api/api';
|
||||
import { putPetItemInteract, getItemIcon, getItemInfo } from '../../services/api/api';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { GameItem, ItemRarity } from '../../types/GameItem';
|
||||
|
||||
interface InventoryModalProps {
|
||||
inventory: Inventory;
|
||||
@@ -17,6 +18,15 @@ export default function InventoryModal({ inventory, petId, onClose, onPetUpdate
|
||||
const [selectedItemIndex, setSelectedItemIndex] = useState<number | null>(null);
|
||||
const [itemIcons, setItemIcons] = useState<Map<number, string>>(new Map());
|
||||
const [loadingIcons, setLoadingIcons] = useState<Set<number>>(new Set());
|
||||
const [selectedItemDetails, setSelectedItemDetails] = useState<GameItem | null>(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 () => {
|
||||
@@ -56,12 +66,26 @@ export default function InventoryModal({ inventory, petId, onClose, onPetUpdate
|
||||
};
|
||||
}, [items]);
|
||||
|
||||
const handleItemClick = (index: number) => {
|
||||
const handleItemClick = async (index: number) => {
|
||||
if (selectedItemIndex === index || gridSlots[index] === undefined) {
|
||||
setSelectedItemIndex(null);
|
||||
setSelectedItemIndex(null);
|
||||
setSelectedItemDetails(null);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
setSelectedItemIndex(index);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -112,6 +136,35 @@ export default function InventoryModal({ inventory, petId, onClose, onPetUpdate
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{selectedItemIndex !== null && (
|
||||
<div className="mt-4 mb-4 p-4 bg-gray-700 rounded">
|
||||
{loadingDetails ? (
|
||||
<div className="flex justify-center">
|
||||
<Loader2 className="w-6 h-6 animate-spin" />
|
||||
</div>
|
||||
) : selectedItemDetails ? (
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-lg font-semibold text-white mb-1">
|
||||
{selectedItemDetails.name}
|
||||
</h3>
|
||||
<div className="flex gap-2 items-center">
|
||||
<span className={rarityColors[selectedItemDetails.rarity]}>
|
||||
{selectedItemDetails.rarity}
|
||||
</span>
|
||||
<span className="text-gray-300">•</span>
|
||||
<span className="text-gray-200">{selectedItemDetails.type}</span>
|
||||
</div>
|
||||
<div className="text-gray-300 text-sm space-y-1">
|
||||
{selectedItemDetails.description.split(';').map((line, index) => (
|
||||
<p key={index}>{line.trim()}</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-4 grid grid-cols-4 gap-4">
|
||||
<button
|
||||
disabled={selectedItemIndex === null}
|
||||
|
||||
Reference in New Issue
Block a user