refactor: streamline GamePhase header and integrate PlayerStatusBar
Clean up duplicate information and improve screen real estate usage: - Replace verbose header with minimal game mode indicator - Remove redundant static information (difficulty, player count details) - Integrate new PlayerStatusBar for comprehensive player state display - Reduce header padding and visual weight - Show helpful tips only at game start and hide after first move - Maintain essential controls (New Game button) in cleaner layout Recovers significant screen space while maintaining all essential functionality and improving visual hierarchy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { useMemoryPairs } from '../context/MemoryPairsContext'
|
||||
import { useGameMode } from '../../../../contexts/GameModeContext'
|
||||
import { MemoryGrid } from './MemoryGrid'
|
||||
import { PlayerStatusBar } from './PlayerStatusBar'
|
||||
import { css } from '../../../../../styled-system/css'
|
||||
|
||||
export function GamePhase() {
|
||||
@@ -22,170 +23,84 @@ export function GamePhase() {
|
||||
flexDirection: 'column'
|
||||
})}>
|
||||
|
||||
{/* Game Header - Compact on mobile */}
|
||||
{/* Minimal Game Header */}
|
||||
<div className={css({
|
||||
background: 'linear-gradient(135deg, rgba(102, 126, 234, 0.1), rgba(118, 75, 162, 0.1))',
|
||||
padding: { base: '8px 12px', sm: '12px 16px', md: '16px 20px' },
|
||||
borderRadius: { base: '8px', md: '12px' },
|
||||
marginBottom: { base: '8px', sm: '12px', md: '16px' },
|
||||
border: '1px solid rgba(102, 126, 234, 0.2)',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: { base: '8px 12px', sm: '10px 16px', md: '12px 20px' },
|
||||
background: 'linear-gradient(135deg, rgba(102, 126, 234, 0.08), rgba(118, 75, 162, 0.08))',
|
||||
borderRadius: '12px',
|
||||
marginBottom: { base: '12px', sm: '16px', md: '20px' },
|
||||
border: '1px solid rgba(102, 126, 234, 0.15)',
|
||||
flexShrink: 0
|
||||
})}>
|
||||
|
||||
{/* Game Mode Indicator - Compact */}
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
gap: { base: '8px', sm: '12px', md: '16px' }
|
||||
gap: '8px',
|
||||
fontSize: { base: '14px', sm: '15px' },
|
||||
fontWeight: 'bold',
|
||||
color: 'gray.600'
|
||||
})}>
|
||||
|
||||
{/* Game Type & Difficulty Info - Hidden on mobile */}
|
||||
<div className={css({
|
||||
display: { base: 'none', sm: 'flex' },
|
||||
alignItems: 'center',
|
||||
gap: { base: '8px', md: '16px' }
|
||||
})}>
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
padding: '8px 16px',
|
||||
background: 'white',
|
||||
borderRadius: '12px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
||||
})}>
|
||||
<span className={css({ fontSize: '20px' })}>
|
||||
{state.gameType === 'abacus-numeral' ? '🧮🔢' : '🤝➕'}
|
||||
</span>
|
||||
<span className={css({ fontWeight: 'bold', color: 'gray.700' })}>
|
||||
{state.gameType === 'abacus-numeral' ? 'Abacus-Numeral' : 'Complement Pairs'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
padding: '8px 16px',
|
||||
background: 'white',
|
||||
borderRadius: '12px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
||||
})}>
|
||||
<span className={css({ fontSize: '20px' })}>
|
||||
{state.difficulty === 6 ? '🌱' : state.difficulty === 8 ? '⚡' : state.difficulty === 12 ? '🔥' : '💀'}
|
||||
</span>
|
||||
<span className={css({ fontWeight: 'bold', color: 'gray.700' })}>
|
||||
{state.difficulty} pairs
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{state.gameMode === 'multiplayer' && (
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
padding: '8px 16px',
|
||||
background: 'white',
|
||||
borderRadius: '12px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
||||
})}>
|
||||
<span className={css({ fontSize: '20px' })}>⚔️</span>
|
||||
<span className={css({ fontWeight: 'bold', color: 'gray.700' })}>
|
||||
{activePlayers.length} Players
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Game Controls */}
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px'
|
||||
})}>
|
||||
|
||||
{/* Restart Button */}
|
||||
<button
|
||||
className={css({
|
||||
background: 'linear-gradient(135deg, #ffeaa7, #fab1a0)',
|
||||
color: '#2d3436',
|
||||
border: 'none',
|
||||
borderRadius: '12px',
|
||||
padding: '10px 16px',
|
||||
fontSize: '14px',
|
||||
fontWeight: 'bold',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.2s ease',
|
||||
boxShadow: '0 2px 8px rgba(255, 234, 167, 0.4)',
|
||||
_hover: {
|
||||
transform: 'translateY(-2px)',
|
||||
boxShadow: '0 4px 12px rgba(255, 234, 167, 0.6)',
|
||||
background: 'linear-gradient(135deg, #fdcb6e, #e17055)'
|
||||
}
|
||||
})}
|
||||
onClick={resetGame}
|
||||
>
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '6px'
|
||||
})}>
|
||||
<span>🔄</span>
|
||||
<span>New Game</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{/* Timer (if multiplayer mode) */}
|
||||
{state.gameMode === 'multiplayer' && (
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
padding: '8px 16px',
|
||||
background: 'white',
|
||||
borderRadius: '12px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
||||
})}>
|
||||
<span className={css({ fontSize: '16px' })}>⏰</span>
|
||||
<span className={css({ fontWeight: 'bold', color: 'gray.700' })}>
|
||||
{state.turnTimer}s per turn
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<span className={css({ fontSize: { base: '16px', sm: '18px' } })}>
|
||||
{state.gameType === 'abacus-numeral' ? '🧮' : '🤝'}
|
||||
</span>
|
||||
<span className={css({ display: { base: 'none', sm: 'inline' } })}>
|
||||
{state.gameType === 'abacus-numeral' ? 'Abacus Match' : 'Complement Pairs'}
|
||||
</span>
|
||||
{state.gameMode === 'multiplayer' && (
|
||||
<>
|
||||
<span className={css({ color: 'gray.400' })}>•</span>
|
||||
<span>⚔️ {activePlayers.length}P</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Current Player Indicator (Multiplayer Mode) - Compact on mobile */}
|
||||
{state.gameMode === 'multiplayer' && currentPlayerData && (
|
||||
<div className={css({
|
||||
marginTop: { base: '8px', md: '12px' },
|
||||
textAlign: 'center'
|
||||
})}>
|
||||
<div className={css({
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: { base: '6px', sm: '8px', md: '12px' },
|
||||
padding: { base: '6px 12px', sm: '8px 16px', md: '12px 24px' },
|
||||
background: `linear-gradient(135deg, ${currentPlayerData.color}, ${currentPlayerData.color}dd)`,
|
||||
color: 'white',
|
||||
borderRadius: { base: '12px', md: '20px' },
|
||||
fontSize: { base: '12px', sm: '14px', md: '16px' },
|
||||
{/* Game Controls */}
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px'
|
||||
})}>
|
||||
{/* New Game Button */}
|
||||
<button
|
||||
className={css({
|
||||
background: 'linear-gradient(135deg, #ffeaa7, #fab1a0)',
|
||||
color: '#2d3436',
|
||||
border: 'none',
|
||||
borderRadius: '10px',
|
||||
padding: { base: '8px 12px', sm: '10px 16px' },
|
||||
fontSize: { base: '13px', sm: '14px' },
|
||||
fontWeight: 'bold',
|
||||
boxShadow: '0 4px 12px rgba(0,0,0,0.2)'
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.2s ease',
|
||||
boxShadow: '0 2px 6px rgba(255, 234, 167, 0.3)',
|
||||
_hover: {
|
||||
transform: 'translateY(-1px)',
|
||||
boxShadow: '0 3px 8px rgba(255, 234, 167, 0.5)',
|
||||
background: 'linear-gradient(135deg, #fdcb6e, #e17055)'
|
||||
}
|
||||
})}
|
||||
onClick={resetGame}
|
||||
>
|
||||
<div className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '6px'
|
||||
})}>
|
||||
<span className={css({ fontSize: { base: '20px', sm: '28px', md: '36px' } })}>
|
||||
{currentPlayerData.emoji}
|
||||
</span>
|
||||
<span className={css({ display: { base: 'none', sm: 'inline' } })}>{currentPlayerData.name}'s Turn</span>
|
||||
<span className={css({ display: { base: 'inline', sm: 'none' } })}>Turn</span>
|
||||
<span className={css({ fontSize: { base: '16px', sm: '20px', md: '24px' } })}>
|
||||
🎯
|
||||
</span>
|
||||
<span>🔄</span>
|
||||
<span>New Game</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Player Status Bar */}
|
||||
<PlayerStatusBar />
|
||||
|
||||
{/* Memory Grid - The main game area */}
|
||||
<div className={css({
|
||||
flex: 1,
|
||||
@@ -197,39 +112,31 @@ export function GamePhase() {
|
||||
<MemoryGrid />
|
||||
</div>
|
||||
|
||||
{/* Helpful Instructions - Hidden on mobile */}
|
||||
<div className={css({
|
||||
textAlign: 'center',
|
||||
marginTop: { base: '8px', md: '16px' },
|
||||
padding: { base: '8px', md: '12px' },
|
||||
background: 'rgba(248, 250, 252, 0.8)',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid rgba(226, 232, 240, 0.8)',
|
||||
display: { base: 'none', md: 'block' },
|
||||
flexShrink: 0
|
||||
})}>
|
||||
<p className={css({
|
||||
fontSize: '14px',
|
||||
color: 'gray.600',
|
||||
margin: 0,
|
||||
lineHeight: '1.4'
|
||||
{/* Quick Tip - Only show when game is starting and on larger screens */}
|
||||
{state.moves === 0 && (
|
||||
<div className={css({
|
||||
textAlign: 'center',
|
||||
marginTop: '12px',
|
||||
padding: '8px 16px',
|
||||
background: 'rgba(248, 250, 252, 0.7)',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid rgba(226, 232, 240, 0.6)',
|
||||
display: { base: 'none', lg: 'block' },
|
||||
flexShrink: 0
|
||||
})}>
|
||||
{state.gameType === 'abacus-numeral'
|
||||
? 'Match abacus representations with their numerical values! Look for patterns and remember card positions.'
|
||||
: 'Find pairs of numbers that add up to 5 or 10! These are called "complement pairs" or "number friends".'
|
||||
}
|
||||
</p>
|
||||
|
||||
{state.gameMode === 'multiplayer' && (
|
||||
<p className={css({
|
||||
fontSize: '12px',
|
||||
color: 'gray.500',
|
||||
margin: '6px 0 0 0'
|
||||
fontSize: '13px',
|
||||
color: 'gray.600',
|
||||
margin: 0,
|
||||
fontWeight: 'medium'
|
||||
})}>
|
||||
Take turns finding matches. The player with the most pairs wins!
|
||||
💡 {state.gameType === 'abacus-numeral'
|
||||
? 'Match abacus beads with numbers'
|
||||
: 'Find pairs that add to 5 or 10'
|
||||
}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user