import { useState } from 'react' import { useTranslation } from 'react-i18next' import type { PlayerState, Profile, Equipment } from './types' import { getAssetPath } from '../../utils/assetPath' import { getTranslatedText } from '../../utils/i18nUtils' import InventoryModal from './InventoryModal' interface PlayerSidebarProps { playerState: PlayerState profile: Profile | null equipment: Equipment inventoryFilter: string inventoryCategoryFilter: string mobileMenuOpen: string onSetInventoryFilter: (filter: string) => void onSetInventoryCategoryFilter: (category: string) => void onUseItem: (itemId: number, invId: number) => void onEquipItem: (invId: number) => void onUnequipItem: (slot: string) => void onDropItem: (itemId: number, invId: number, quantity: number) => void onSpendPoint: (stat: string) => void } function PlayerSidebar({ playerState, profile, equipment, inventoryFilter, inventoryCategoryFilter, mobileMenuOpen, onSetInventoryFilter, onSetInventoryCategoryFilter, onUseItem, onEquipItem, onUnequipItem, onDropItem, onSpendPoint }: PlayerSidebarProps) { const [showInventory, setShowInventory] = useState(false) const { t } = useTranslation() const renderEquipmentSlot = (slot: string, item: any, emoji: string, label: string) => (
{item ? ( <>
{item.image_path ? ( {getTranslatedText(item.name)} { (e.target as HTMLImageElement).style.display = 'none'; const icon = (e.target as HTMLImageElement).nextElementSibling; if (icon) icon.classList.remove('hidden'); }} /> ) : null} {item.emoji} {getTranslatedText(item.name)} {item.durability && item.durability !== null && ( {item.durability}/{item.max_durability} )}
{item.description &&
{getTranslatedText(item.description)}
} {/* Use unique_stats if available, otherwise fall back to base stats */} {(item.unique_stats || item.stats) && Object.keys(item.unique_stats || item.stats).length > 0 && ( <> {(item.unique_stats?.armor || item.stats?.armor) && (
{t('stats.armor')}: +{item.unique_stats?.armor || item.stats?.armor}
)} {(item.unique_stats?.hp_max || item.stats?.hp_max) && (
{t('stats.hp')}: +{item.unique_stats?.hp_max || item.stats?.hp_max}
)} {(item.unique_stats?.stamina_max || item.stats?.stamina_max) && (
{t('stats.stamina')}: +{item.unique_stats?.stamina_max || item.stats?.stamina_max}
)} {(item.unique_stats?.damage_min !== undefined || item.stats?.damage_min !== undefined) && (item.unique_stats?.damage_max !== undefined || item.stats?.damage_max !== undefined) && (
{t('stats.damage')}: {item.unique_stats?.damage_min || item.stats?.damage_min}-{item.unique_stats?.damage_max || item.stats?.damage_max}
)} {(item.unique_stats?.weight_capacity || item.stats?.weight_capacity) && (
{t('stats.weight')}: +{item.unique_stats?.weight_capacity || item.stats?.weight_capacity}kg
)} {(item.unique_stats?.volume_capacity || item.stats?.volume_capacity) && (
{t('stats.volume')}: +{item.unique_stats?.volume_capacity || item.stats?.volume_capacity}L
)} )} {item.durability !== undefined && item.durability !== null && (
{t('stats.durability')}: {item.durability}/{item.max_durability}
)} {item.tier !== undefined && item.tier !== null && item.tier > 0 && (
⭐ Tier: {item.tier}
)}
) : ( <> {emoji} {label} )}
) return (
{/* Profile Stats */}

{t('game.character')}

{t('stats.hp')} {playerState.health}/{playerState.max_health}
{Math.round((playerState.health / playerState.max_health) * 100)}%
{t('stats.stamina')} {playerState.stamina}/{playerState.max_stamina}
{Math.round((playerState.stamina / playerState.max_stamina) * 100)}%
{profile && (
{t('stats.level')}: {profile.level}
{t('stats.xp')} {profile.xp} / {(profile.level * 100)}
{Math.round((profile.xp / (profile.level * 100)) * 100)}%
{profile.unspent_points > 0 && (
{t('stats.unspentPoints')}: {profile.unspent_points}
)}
{/* Compact 2x2 Stats Grid */}
{t('stats.strength')}: {profile.strength} {profile.unspent_points > 0 && ( )}
{t('stats.agility')}: {profile.agility} {profile.unspent_points > 0 && ( )}
{t('stats.endurance')}: {profile.endurance} {profile.unspent_points > 0 && ( )}
{t('stats.intellect')}: {profile.intellect} {profile.unspent_points > 0 && ( )}
{/* Inventory Capacity - matching HP/Stamina/XP style */}
{t('stats.weight')} {(profile.current_weight || 0).toFixed(1)}/{profile.max_weight || 0}kg
{Math.round(Math.min(100, ((profile.current_weight || 0) / (profile.max_weight || 1)) * 100))}%
{t('stats.volume')} {(profile.current_volume || 0).toFixed(1)}/{profile.max_volume || 0}L
{Math.round(Math.min(100, ((profile.current_volume || 0) / (profile.max_volume || 1)) * 100))}%
)}
{/* Equipment Display - Proper Grid Layout */}

{t('game.equipment')}

{/* Row 1: Head */}
{renderEquipmentSlot('head', equipment.head, '🪖', t('equipment.head'))}
{/* Row 2: Weapon, Torso, Backpack */}
{renderEquipmentSlot('weapon', equipment.weapon, '⚔️', t('equipment.weapon'))} {renderEquipmentSlot('torso', equipment.torso, '👕', t('equipment.torso'))} {renderEquipmentSlot('backpack', equipment.backpack, '🎒', t('equipment.backpack'))}
{/* Row 3: Legs & Feet */}
{renderEquipmentSlot('legs', equipment.legs, '👖', t('equipment.legs'))} {renderEquipmentSlot('feet', equipment.feet, '👟', t('equipment.feet'))}
{/* Inventory Modal */} {showInventory && profile && ( setShowInventory(false)} onSetInventoryFilter={onSetInventoryFilter} onSetInventoryCategoryFilter={onSetInventoryCategoryFilter} onUseItem={onUseItem} onEquipItem={onEquipItem} onUnequipItem={onUnequipItem} onDropItem={onDropItem} /> )}
) } export default PlayerSidebar