'use client'; import { useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Separator } from '@/components/ui/separator'; import { Input } from '@/components/ui/input'; import { Gem, Sparkles, Scroll, Droplet, Trash2, Search, Package, Sword, Shield, Shirt, Crown, ArrowUpDown, Wrench, AlertTriangle } from 'lucide-react'; import type { LootInventory as LootInventoryType, EquipmentInstance, ElementState } from '@/lib/game/types'; import { LOOT_DROPS, RARITY_COLORS } from '@/lib/game/data/loot-drops'; import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment'; import { ELEMENTS } from '@/lib/game/constants'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; interface LootInventoryProps { inventory: LootInventoryType; elements?: Record; equipmentInstances?: Record; onDeleteMaterial?: (materialId: string, amount: number) => void; onDeleteEquipment?: (instanceId: string) => void; } type SortMode = 'name' | 'rarity' | 'count'; type FilterMode = 'all' | 'materials' | 'essence' | 'blueprints' | 'equipment'; const RARITY_ORDER = { common: 0, uncommon: 1, rare: 2, epic: 3, legendary: 4, mythic: 5, }; const CATEGORY_ICONS: Record = { caster: Sword, shield: Shield, catalyst: Sparkles, head: Crown, body: Shirt, hands: Wrench, feet: Package, accessory: Gem, }; export function LootInventoryDisplay({ inventory, elements, equipmentInstances = {}, onDeleteMaterial, onDeleteEquipment, }: LootInventoryProps) { const [searchTerm, setSearchTerm] = useState(''); const [sortMode, setSortMode] = useState('rarity'); const [filterMode, setFilterMode] = useState('all'); const [deleteConfirm, setDeleteConfirm] = useState<{ type: 'material' | 'equipment'; id: string; name: string } | null>(null); // Count items const materialCount = Object.values(inventory.materials).reduce((a, b) => a + b, 0); const essenceCount = elements ? Object.values(elements).reduce((a, e) => a + e.current, 0) : 0; const blueprintCount = inventory.blueprints.length; const equipmentCount = Object.keys(equipmentInstances).length; const totalItems = materialCount + blueprintCount + equipmentCount; // Filter and sort materials const filteredMaterials = Object.entries(inventory.materials) .filter(([id, count]) => { if (count <= 0) return false; const drop = LOOT_DROPS[id]; if (!drop) return false; if (searchTerm && !drop.name.toLowerCase().includes(searchTerm.toLowerCase())) return false; return true; }) .sort(([aId, aCount], [bId, bCount]) => { const aDrop = LOOT_DROPS[aId]; const bDrop = LOOT_DROPS[bId]; if (!aDrop || !bDrop) return 0; switch (sortMode) { case 'name': return aDrop.name.localeCompare(bDrop.name); case 'rarity': return RARITY_ORDER[bDrop.rarity] - RARITY_ORDER[aDrop.rarity]; case 'count': return bCount - aCount; default: return 0; } }); // Filter and sort essence const filteredEssence = elements ? Object.entries(elements) .filter(([id, state]) => { if (!state.unlocked || state.current <= 0) return false; if (searchTerm && !ELEMENTS[id]?.name.toLowerCase().includes(searchTerm.toLowerCase())) return false; return true; }) .sort(([aId, aState], [bId, bState]) => { switch (sortMode) { case 'name': return (ELEMENTS[aId]?.name || aId).localeCompare(ELEMENTS[bId]?.name || bId); case 'count': return bState.current - aState.current; default: return 0; } }) : []; // Filter and sort equipment const filteredEquipment = Object.entries(equipmentInstances) .filter(([id, instance]) => { if (searchTerm && !instance.name.toLowerCase().includes(searchTerm.toLowerCase())) return false; return true; }) .sort(([aId, aInst], [bId, bInst]) => { switch (sortMode) { case 'name': return aInst.name.localeCompare(bInst.name); case 'rarity': return RARITY_ORDER[bInst.rarity] - RARITY_ORDER[aInst.rarity]; default: return 0; } }); // Check if we have anything to show const hasItems = totalItems > 0 || essenceCount > 0; if (!hasItems) { return ( Inventory
No items collected yet. Defeat floors and guardians to find loot!
); } const handleDeleteMaterial = (materialId: string) => { const drop = LOOT_DROPS[materialId]; if (drop) { setDeleteConfirm({ type: 'material', id: materialId, name: drop.name }); } }; const handleDeleteEquipment = (instanceId: string) => { const instance = equipmentInstances[instanceId]; if (instance) { setDeleteConfirm({ type: 'equipment', id: instanceId, name: instance.name }); } }; const confirmDelete = () => { if (!deleteConfirm) return; if (deleteConfirm.type === 'material' && onDeleteMaterial) { onDeleteMaterial(deleteConfirm.id, inventory.materials[deleteConfirm.id] || 0); } else if (deleteConfirm.type === 'equipment' && onDeleteEquipment) { onDeleteEquipment(deleteConfirm.id); } setDeleteConfirm(null); }; return ( <> Inventory {totalItems} items {/* Search and Filter Controls */}
setSearchTerm(e.target.value)} className="h-7 pl-7 bg-gray-800/50 border-gray-700 text-xs" />
{/* Filter Tabs */}
{[ { mode: 'all' as FilterMode, label: 'All' }, { mode: 'materials' as FilterMode, label: `Materials (${materialCount})` }, { mode: 'essence' as FilterMode, label: `Essence (${essenceCount})` }, { mode: 'blueprints' as FilterMode, label: `Blueprints (${blueprintCount})` }, { mode: 'equipment' as FilterMode, label: `Equipment (${equipmentCount})` }, ].map(({ mode, label }) => ( ))}
{/* Materials */} {(filterMode === 'all' || filterMode === 'materials') && filteredMaterials.length > 0 && (
Materials
{filteredMaterials.map(([id, count]) => { const drop = LOOT_DROPS[id]; if (!drop) return null; const rarityStyle = RARITY_COLORS[drop.rarity]; return (
{drop.name}
x{count}
{drop.rarity}
{onDeleteMaterial && ( )}
); })}
)} {/* Essence */} {(filterMode === 'all' || filterMode === 'essence') && filteredEssence.length > 0 && (
Elemental Essence
{filteredEssence.map(([id, state]) => { const elem = ELEMENTS[id]; if (!elem) return null; return (
{elem.sym} {elem.name}
{state.current} / {state.max}
); })}
)} {/* Blueprints */} {(filterMode === 'all' || filterMode === 'blueprints') && inventory.blueprints.length > 0 && (
Blueprints (permanent)
{inventory.blueprints.map((id) => { const drop = LOOT_DROPS[id]; if (!drop) return null; const rarityStyle = RARITY_COLORS[drop.rarity]; return ( {drop.name} ); })}
Blueprints are permanent unlocks - use them to craft equipment
)} {/* Equipment */} {(filterMode === 'all' || filterMode === 'equipment') && filteredEquipment.length > 0 && (
Equipment
{filteredEquipment.map(([id, instance]) => { const type = EQUIPMENT_TYPES[instance.typeId]; const Icon = type ? CATEGORY_ICONS[type.category] || Package : Package; const rarityStyle = RARITY_COLORS[instance.rarity]; return (
{instance.name}
{type?.name} • {instance.usedCapacity}/{instance.totalCapacity} cap
{instance.rarity} • {instance.enchantments.length} enchants
{onDeleteEquipment && ( )}
); })}
)}
{/* Delete Confirmation Dialog */} setDeleteConfirm(null)}> Delete Item Are you sure you want to delete {deleteConfirm?.name}? {deleteConfirm?.type === 'material' && ( This will delete ALL {inventory.materials[deleteConfirm?.id || ''] || 0} of this material! )} {deleteConfirm?.type === 'equipment' && ( This equipment and all its enchantments will be permanently lost! )} Cancel Delete ); }