fix(build): remove unused useRef from LocationView
This commit is contained in:
119
pwa/src/components/game/LocationView.css
Normal file
119
pwa/src/components/game/LocationView.css
Normal file
@@ -0,0 +1,119 @@
|
||||
/* Grid View Styles */
|
||||
.entity-list.grid-view {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||
gap: 1rem;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.entity-card.grid-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
aspect-ratio: 1;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border: 1px solid var(--game-border-color);
|
||||
border-radius: 8px;
|
||||
/* Slightly more rounded for grid items */
|
||||
transition: all 0.2s;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.entity-card.grid-card:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
border-color: var(--game-text-highlight);
|
||||
}
|
||||
|
||||
.grid-card .entity-image {
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
margin-bottom: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.grid-card .entity-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.grid-card .grid-quantity {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: #fff;
|
||||
font-size: 0.75rem;
|
||||
padding: 1px 4px;
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.grid-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.grid-corpse-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Specific Border Colors for Grid Cards to match List View */
|
||||
.enemy-card.grid-card {
|
||||
border-color: rgba(244, 67, 54, 0.5);
|
||||
}
|
||||
|
||||
.enemy-card.grid-card:hover {
|
||||
border-color: rgba(244, 67, 54, 1);
|
||||
background: rgba(244, 67, 54, 0.1);
|
||||
}
|
||||
|
||||
.corpse-card.grid-card {
|
||||
border-color: rgba(156, 39, 176, 0.5);
|
||||
}
|
||||
|
||||
.corpse-card.grid-card:hover {
|
||||
border-color: rgba(156, 39, 176, 1);
|
||||
background: rgba(156, 39, 176, 0.1);
|
||||
}
|
||||
|
||||
.npc-card.grid-card {
|
||||
border-color: rgba(107, 185, 240, 0.5);
|
||||
}
|
||||
|
||||
.npc-card.grid-card:hover {
|
||||
border-color: rgba(107, 185, 240, 1);
|
||||
background: rgba(107, 185, 240, 0.1);
|
||||
}
|
||||
|
||||
.item-card.grid-card {
|
||||
border-color: rgba(76, 175, 80, 0.5);
|
||||
}
|
||||
|
||||
.item-card.grid-card:hover {
|
||||
border-color: rgba(76, 175, 80, 1);
|
||||
background: rgba(76, 175, 80, 0.1);
|
||||
}
|
||||
|
||||
.view-toggle-btn {
|
||||
border: 1px solid var(--game-border-color);
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
import type { Location, PlayerState, CombatState, Profile, WorkbenchTab } from './types'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useAudio } from '../../contexts/AudioContext'
|
||||
import Workbench from './Workbench'
|
||||
import { GameTooltip } from '../common/GameTooltip'
|
||||
import { GameButton } from '../common/GameButton'
|
||||
import { GameDropdown } from '../common/GameDropdown'
|
||||
import { getAssetPath } from '../../utils/assetPath'
|
||||
import { getTranslatedText } from '../../utils/i18nUtils'
|
||||
import './LocationView.css'
|
||||
|
||||
interface LocationViewProps {
|
||||
location: Location
|
||||
@@ -88,6 +92,44 @@ function LocationView({
|
||||
const { t } = useTranslation()
|
||||
const { playSfx } = useAudio()
|
||||
|
||||
// View Mode State
|
||||
const [viewMode, setViewMode] = useState<'list' | 'grid'>(() => {
|
||||
return (localStorage.getItem('locationViewMode') as 'list' | 'grid') || 'list'
|
||||
})
|
||||
|
||||
// Dropdown State
|
||||
const [activeDropdown, setActiveDropdown] = useState<string | null>(null)
|
||||
const [dropdownPos, setDropdownPos] = useState({ x: 0, y: 0 })
|
||||
|
||||
const toggleViewMode = () => {
|
||||
const newMode = viewMode === 'list' ? 'grid' : 'list'
|
||||
setViewMode(newMode)
|
||||
localStorage.setItem('locationViewMode', newMode)
|
||||
playSfx('/audio/sfx/click.wav')
|
||||
}
|
||||
|
||||
// Handle dropdown toggle
|
||||
const handleDropdownClick = (e: React.MouseEvent, id: string) => {
|
||||
e.stopPropagation()
|
||||
if (activeDropdown === id) {
|
||||
setActiveDropdown(null)
|
||||
} else {
|
||||
const rect = e.currentTarget.getBoundingClientRect()
|
||||
setDropdownPos({
|
||||
x: rect.left + window.scrollX,
|
||||
y: rect.bottom + window.scrollY + 5
|
||||
})
|
||||
setActiveDropdown(id)
|
||||
}
|
||||
}
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
useEffect(() => {
|
||||
const handleClickOutside = () => setActiveDropdown(null)
|
||||
window.addEventListener('click', handleClickOutside)
|
||||
return () => window.removeEventListener('click', handleClickOutside)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="location-view">
|
||||
<div className="location-info">
|
||||
@@ -105,6 +147,15 @@ function LocationView({
|
||||
</span>
|
||||
</GameTooltip>
|
||||
)}
|
||||
<GameButton
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={(e) => { e.stopPropagation(); toggleViewMode(); }}
|
||||
className="view-toggle-btn"
|
||||
style={{ marginLeft: 'auto' }}
|
||||
>
|
||||
{viewMode === 'list' ? '📋' : '🔲'}
|
||||
</GameButton>
|
||||
</h2>
|
||||
|
||||
{location.tags && location.tags.length > 0 && (
|
||||
@@ -179,34 +230,82 @@ function LocationView({
|
||||
)}
|
||||
|
||||
<div className={`ground-entities mobile-menu-panel bottom ${mobileMenuOpen === 'bottom' ? 'open' : ''}`}>
|
||||
{/* Enemies */}
|
||||
{/* Enemies */}
|
||||
{location.npcs.filter((npc: any) => npc.type === 'enemy').length > 0 && (
|
||||
<div className="entity-section enemies-section">
|
||||
<h3>{t('location.enemies')}</h3>
|
||||
<div className="entity-list">
|
||||
{location.npcs.filter((npc: any) => npc.type === 'enemy').map((enemy: any, i: number) => (
|
||||
<div key={i} className="entity-card enemy-card">
|
||||
{enemy.id && (
|
||||
<div className="entity-image">
|
||||
<img
|
||||
src={getAssetPath(enemy.image_path || `images/npcs/${(typeof enemy.name === 'string' ? enemy.name : enemy.name?.en || '').toLowerCase().replace(/ /g, '_')}.webp`)}
|
||||
alt={getTranslatedText(enemy.name)}
|
||||
onError={(e: any) => { e.currentTarget.style.display = 'none' }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="entity-info">
|
||||
<div className="entity-name enemy-name">{getTranslatedText(enemy.name)}</div>
|
||||
{enemy.level && <div className="entity-level">{t('location.level')} {enemy.level}</div>}
|
||||
<div className={`entity-list ${viewMode === 'grid' ? 'grid-view' : ''}`}>
|
||||
{location.npcs.filter((npc: any) => npc.type === 'enemy').map((enemy: any, i: number) => {
|
||||
const id = `enemy-${enemy.id || i}`;
|
||||
return (
|
||||
<div key={i} className={`entity-card enemy-card ${viewMode === 'grid' ? 'grid-card' : ''}`}
|
||||
onClick={viewMode === 'grid' ? (e) => handleDropdownClick(e, id) : undefined}>
|
||||
{enemy.id && (
|
||||
<div className="entity-image">
|
||||
<img
|
||||
src={getAssetPath(enemy.image_path || `images/npcs/${(typeof enemy.name === 'string' ? enemy.name : enemy.name?.en || '').toLowerCase().replace(/ /g, '_')}.webp`)}
|
||||
alt={getTranslatedText(enemy.name)}
|
||||
onError={(e: any) => { e.currentTarget.style.display = 'none' }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{viewMode === 'list' && (
|
||||
<>
|
||||
<div className="entity-info">
|
||||
<div className="entity-name enemy-name">{getTranslatedText(enemy.name)}</div>
|
||||
{enemy.level && <div className="entity-level">{t('location.level')} {enemy.level}</div>}
|
||||
</div>
|
||||
<GameButton
|
||||
variant="danger"
|
||||
size="sm"
|
||||
className="entity-action-btn combat-btn"
|
||||
onClick={() => onInitiateCombat(enemy.id)}
|
||||
>
|
||||
{t('common.fight')}
|
||||
</GameButton>
|
||||
</>
|
||||
)}
|
||||
|
||||
{viewMode === 'grid' && (
|
||||
<GameTooltip content={
|
||||
<div>
|
||||
<div className="tooltip-title">{getTranslatedText(enemy.name)}</div>
|
||||
<div>{t('location.level')} {enemy.level}</div>
|
||||
<div style={{ color: '#f56565', fontSize: '0.8rem' }}>Click for actions</div>
|
||||
</div>
|
||||
}>
|
||||
<div className="grid-overlay"></div>
|
||||
</GameTooltip>
|
||||
)}
|
||||
|
||||
{/* Dropdown for Grid View */}
|
||||
{viewMode === 'grid' && activeDropdown === id && (
|
||||
<GameDropdown
|
||||
isOpen={true}
|
||||
onClose={() => setActiveDropdown(null)}
|
||||
position={dropdownPos}
|
||||
width="160px"
|
||||
>
|
||||
<div className="game-dropdown-header">{getTranslatedText(enemy.name)}</div>
|
||||
<GameButton
|
||||
variant="danger"
|
||||
size="sm"
|
||||
onClick={() => { onInitiateCombat(enemy.id); setActiveDropdown(null); }}
|
||||
style={{ width: '100%', justifyContent: 'flex-start' }}
|
||||
>
|
||||
⚔️ {t('common.fight')}
|
||||
</GameButton>
|
||||
<div className="game-dropdown-divider" />
|
||||
<div style={{ padding: '0.5rem', fontSize: '0.8rem', color: '#a0aec0' }}>
|
||||
{t('location.level')} {enemy.level}
|
||||
</div>
|
||||
</GameDropdown>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
className="entity-action-btn combat-btn"
|
||||
onClick={() => onInitiateCombat(enemy.id)}
|
||||
>
|
||||
{t('common.fight')}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -218,21 +317,65 @@ function LocationView({
|
||||
<div className="entity-list">
|
||||
{location.corpses.map((corpse: any) => (
|
||||
<div key={corpse.id} className="corpse-container">
|
||||
<div className="entity-card corpse-card">
|
||||
<div className="entity-info">
|
||||
<div className="entity-name">{corpse.emoji} {getTranslatedText(corpse.name)}</div>
|
||||
<div className="corpse-loot-count">{corpse.loot_count} {t('location.items')}</div>
|
||||
</div>
|
||||
<button
|
||||
className="entity-action-btn loot-btn"
|
||||
onClick={() => {
|
||||
playSfx('/audio/sfx/interact.wav')
|
||||
onLootCorpse(String(corpse.id))
|
||||
}}
|
||||
disabled={corpse.loot_count === 0}
|
||||
>
|
||||
🔍 {t('common.examine')}
|
||||
</button>
|
||||
<div className={`entity-card corpse-card ${viewMode === 'grid' ? 'grid-card' : ''}`}
|
||||
onClick={viewMode === 'grid' ? (e) => handleDropdownClick(e, `corpse-${corpse.id}`) : undefined}
|
||||
>
|
||||
{viewMode === 'list' ? (
|
||||
<>
|
||||
<div className="entity-info">
|
||||
<div className="entity-name">{corpse.emoji} {getTranslatedText(corpse.name)}</div>
|
||||
<div className="corpse-loot-count">{corpse.loot_count} {t('location.items')}</div>
|
||||
</div>
|
||||
<GameButton
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
className="entity-action-btn loot-btn"
|
||||
onClick={() => {
|
||||
playSfx('/audio/sfx/interact.wav')
|
||||
onLootCorpse(String(corpse.id))
|
||||
}}
|
||||
disabled={corpse.loot_count === 0}
|
||||
>
|
||||
🔍 {t('common.examine')}
|
||||
</GameButton>
|
||||
</>
|
||||
) : (
|
||||
<GameTooltip content={
|
||||
<div>
|
||||
<div className="tooltip-title">{corpse.emoji} {getTranslatedText(corpse.name)}</div>
|
||||
<div>{corpse.loot_count} {t('location.items')}</div>
|
||||
</div>
|
||||
}>
|
||||
<div className="grid-corpse-content">
|
||||
<div style={{ fontSize: '2rem' }}>{corpse.emoji}</div>
|
||||
<div style={{ fontSize: '0.8rem', color: '#ce93d8' }}>{corpse.loot_count} items</div>
|
||||
</div>
|
||||
</GameTooltip>
|
||||
)}
|
||||
|
||||
{viewMode === 'grid' && activeDropdown === `corpse-${corpse.id}` && (
|
||||
<GameDropdown
|
||||
isOpen={true}
|
||||
onClose={() => setActiveDropdown(null)}
|
||||
position={dropdownPos}
|
||||
width="160px"
|
||||
>
|
||||
<div className="game-dropdown-header">{getTranslatedText(corpse.name)}</div>
|
||||
<GameButton
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
playSfx('/audio/sfx/interact.wav')
|
||||
onLootCorpse(String(corpse.id))
|
||||
setActiveDropdown(null)
|
||||
}}
|
||||
disabled={corpse.loot_count === 0}
|
||||
style={{ width: '100%', justifyContent: 'flex-start' }}
|
||||
>
|
||||
🔍 {t('common.examine')}
|
||||
</GameButton>
|
||||
</GameDropdown>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{expandedCorpse === String(corpse.id) && corpseDetails && corpseDetails.loot_items && (
|
||||
@@ -296,13 +439,42 @@ function LocationView({
|
||||
<h3>{t('location.npcs')}</h3>
|
||||
<div className="entity-list">
|
||||
{location.npcs.filter((npc: any) => npc.type !== 'enemy').map((npc: any, i: number) => (
|
||||
<div key={i} className="entity-card npc-card">
|
||||
<span className="entity-icon">🧑</span>
|
||||
<div className="entity-info">
|
||||
<div className="entity-name">{getTranslatedText(npc.name)}</div>
|
||||
{npc.level && <div className="entity-level">{t('location.level')} {npc.level}</div>}
|
||||
</div>
|
||||
<button className="entity-action-btn">{t('common.talk')}</button>
|
||||
<div key={i} className={`entity-card npc-card ${viewMode === 'grid' ? 'grid-card' : ''}`}
|
||||
onClick={viewMode === 'grid' ? (e) => handleDropdownClick(e, `npc-${i}`) : undefined}
|
||||
>
|
||||
<span className="entity-icon" style={viewMode === 'grid' ? { fontSize: '2.5rem' } : {}}>🧑</span>
|
||||
|
||||
{viewMode === 'list' ? (
|
||||
<>
|
||||
<div className="entity-info">
|
||||
<div className="entity-name">{getTranslatedText(npc.name)}</div>
|
||||
{npc.level && <div className="entity-level">{t('location.level')} {npc.level}</div>}
|
||||
</div>
|
||||
<GameButton variant="primary" size="sm" className="entity-action-btn">{t('common.talk')}</GameButton>
|
||||
</>
|
||||
) : (
|
||||
<GameTooltip content={
|
||||
<div>
|
||||
<div className="tooltip-title">{getTranslatedText(npc.name)}</div>
|
||||
<div>{t('location.level')} {npc.level}</div>
|
||||
</div>
|
||||
}>
|
||||
<div className="grid-overlay"></div>
|
||||
</GameTooltip>
|
||||
)}
|
||||
|
||||
{viewMode === 'grid' && activeDropdown === `npc-${i}` && (
|
||||
<GameDropdown
|
||||
isOpen={true}
|
||||
onClose={() => setActiveDropdown(null)}
|
||||
position={dropdownPos}
|
||||
>
|
||||
<div className="game-dropdown-header">{getTranslatedText(npc.name)}</div>
|
||||
<GameButton variant="primary" size="sm" style={{ width: '100%', justifyContent: 'flex-start' }}>
|
||||
💬 {t('common.talk')}
|
||||
</GameButton>
|
||||
</GameDropdown>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -317,8 +489,11 @@ function LocationView({
|
||||
{location.items.map((item: any, i: number) => {
|
||||
// Use loose equality to handle potential string/number mismatches
|
||||
const isShaking = failedActionItemId == item.id;
|
||||
const itemId = `item-${item.id}-${i}`;
|
||||
return (
|
||||
<div key={i} className={`entity-card item-card ${isShaking ? 'shake' : ''}`}>
|
||||
<div key={i} className={`entity-card item-card ${isShaking ? 'shake' : ''} ${viewMode === 'grid' ? 'grid-card' : ''}`}
|
||||
onClick={viewMode === 'grid' ? (e) => handleDropdownClick(e, itemId) : undefined}
|
||||
>
|
||||
<GameTooltip content={
|
||||
<div className="item-info-tooltip-content">
|
||||
{item.description && <div className="item-tooltip-desc">{getTranslatedText(item.description)}</div>}
|
||||
@@ -353,12 +528,13 @@ function LocationView({
|
||||
)}
|
||||
</div>
|
||||
}>
|
||||
<div className="entity-content-wrapper" style={{ display: 'flex', alignItems: 'center', gap: '1rem', flex: 1, cursor: 'help' }}>
|
||||
<div className={`entity-content-wrapper ${viewMode === 'grid' ? 'grid-content' : ''}`} style={viewMode === 'list' ? { display: 'flex', alignItems: 'center', gap: '1rem', flex: 1, cursor: 'help' } : {}}>
|
||||
{item.image_path ? (
|
||||
<img
|
||||
src={getAssetPath(item.image_path)}
|
||||
alt={getTranslatedText(item.name)}
|
||||
className="entity-icon"
|
||||
style={viewMode === 'grid' ? { width: '100%', height: '100%', objectFit: 'contain' } : {}}
|
||||
onError={(e) => {
|
||||
(e.target as HTMLImageElement).style.display = 'none';
|
||||
const icon = (e.target as HTMLImageElement).nextElementSibling;
|
||||
@@ -366,59 +542,98 @@ function LocationView({
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<span className={`entity-icon ${item.image_path ? 'hidden' : ''}`}>{item.emoji || '📦'}</span>
|
||||
<div className="entity-info">
|
||||
<div className={`entity-name ${item.tier ? `tier-${item.tier}` : ''}`}>
|
||||
{getTranslatedText(item.name) || 'Unknown Item'}
|
||||
<span className={`entity-icon ${item.image_path ? 'hidden' : ''}`} style={viewMode === 'grid' && !item.image_path ? { fontSize: '2rem' } : {}}>{item.emoji || '📦'}</span>
|
||||
|
||||
{viewMode === 'list' && (
|
||||
<div className="entity-info">
|
||||
<div className={`entity-name ${item.tier ? `tier-${item.tier}` : ''}`}>
|
||||
{getTranslatedText(item.name) || 'Unknown Item'}
|
||||
</div>
|
||||
{item.quantity > 1 && <div className="entity-quantity">×{item.quantity}</div>}
|
||||
</div>
|
||||
{item.quantity > 1 && <div className="entity-quantity">×{item.quantity}</div>}
|
||||
</div>
|
||||
)}
|
||||
{viewMode === 'grid' && item.quantity > 1 && (
|
||||
<div className="grid-quantity">x{item.quantity}</div>
|
||||
)}
|
||||
</div>
|
||||
</GameTooltip>
|
||||
|
||||
<div className="item-actions-row">
|
||||
{item.quantity === 1 ? (
|
||||
<button
|
||||
className="action-btn pickup single"
|
||||
onClick={() => {
|
||||
// Sound handled in useGameEngine
|
||||
onPickup(item.id, 1)
|
||||
}}
|
||||
{viewMode === 'list' && (
|
||||
<div className="item-actions-row">
|
||||
{item.quantity === 1 ? (
|
||||
<GameButton
|
||||
variant="success"
|
||||
size="sm"
|
||||
className="action-btn pickup single"
|
||||
onClick={() => {
|
||||
// Sound handled in useGameEngine
|
||||
onPickup(item.id, 1)
|
||||
}}
|
||||
>
|
||||
{t('common.pickUp')}
|
||||
</GameButton>
|
||||
) : (
|
||||
<div className="pickup-actions-group">
|
||||
<GameButton variant="success" size="sm" className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, 1)
|
||||
}}>
|
||||
x1
|
||||
</GameButton>
|
||||
|
||||
{item.quantity >= 5 && (
|
||||
<GameButton variant="success" size="sm" className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, 5)
|
||||
}}>
|
||||
x5
|
||||
</GameButton>
|
||||
)}
|
||||
|
||||
{item.quantity >= 10 && (
|
||||
<GameButton variant="success" size="sm" className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, 10)
|
||||
}}>
|
||||
x10
|
||||
</GameButton>
|
||||
)}
|
||||
|
||||
<GameButton variant="success" size="sm" className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, item.quantity)
|
||||
}}>
|
||||
{t('common.all') || 'All'}
|
||||
</GameButton>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{viewMode === 'grid' && activeDropdown === itemId && (
|
||||
<GameDropdown
|
||||
isOpen={true}
|
||||
onClose={() => setActiveDropdown(null)}
|
||||
position={dropdownPos}
|
||||
width="160px"
|
||||
>
|
||||
<div className="game-dropdown-header">{getTranslatedText(item.name)}</div>
|
||||
<GameButton
|
||||
variant="success"
|
||||
size="sm"
|
||||
onClick={() => { onPickup(item.id, 1); setActiveDropdown(null); }}
|
||||
style={{ width: '100%', justifyContent: 'flex-start' }}
|
||||
>
|
||||
{t('common.pickUp')}
|
||||
</button>
|
||||
) : (
|
||||
<div className="pickup-actions-group">
|
||||
<button className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, 1)
|
||||
}}>
|
||||
x1
|
||||
</button>
|
||||
|
||||
{item.quantity >= 5 && (
|
||||
<button className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, 5)
|
||||
}}>
|
||||
x5
|
||||
</button>
|
||||
)}
|
||||
|
||||
{item.quantity >= 10 && (
|
||||
<button className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, 10)
|
||||
}}>
|
||||
x10
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button className="action-btn pickup" onClick={() => {
|
||||
onPickup(item.id, item.quantity)
|
||||
}}>
|
||||
{t('common.all') || 'All'}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
🤚 {t('common.pickUp')} (x1)
|
||||
</GameButton>
|
||||
{item.quantity > 1 && (
|
||||
<GameButton
|
||||
variant="success"
|
||||
size="sm"
|
||||
onClick={() => { onPickup(item.id, item.quantity); setActiveDropdown(null); }}
|
||||
style={{ width: '100%', justifyContent: 'flex-start' }}
|
||||
>
|
||||
🤚 {t('common.pickUp')} ({t('common.all')})
|
||||
</GameButton>
|
||||
)}
|
||||
</GameDropdown>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { getTranslatedText } from '../../utils/i18nUtils'
|
||||
import InventoryModal from './InventoryModal'
|
||||
import { GameProgressBar } from '../common/GameProgressBar'
|
||||
import { GameTooltip } from '../common/GameTooltip'
|
||||
import { GameButton } from '../common/GameButton'
|
||||
import { useAudio } from '../../contexts/AudioContext'
|
||||
|
||||
interface PlayerSidebarProps {
|
||||
@@ -289,12 +290,15 @@ function PlayerSidebar({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<button
|
||||
<GameButton
|
||||
className="open-inventory-btn"
|
||||
variant="primary"
|
||||
size="lg"
|
||||
onClick={() => setShowInventory(true)}
|
||||
style={{ width: '100%', justifyContent: 'center' }}
|
||||
>
|
||||
{t('game.inventory')}
|
||||
</button>
|
||||
</GameButton>
|
||||
</div>
|
||||
|
||||
<div className="equipment-sidebar">
|
||||
|
||||
Reference in New Issue
Block a user