Fix Match: Progress bar + counter, audio on EN column too

- Progress bar under header (fills as pairs are matched)
- Counter with symbols: ✓ first-try, ↻ retry, ✗ errors
- EN column now also has audio buttons (small speaker icon)
- All 3 columns have consistent height (flex layout)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-27 18:35:00 +02:00
parent a1664ab12c
commit 6d54ee8178

View File

@@ -140,12 +140,19 @@ export default function MatchPage() {
{t('back')}
</button>
<h1 className={`text-lg font-bold ${isDark ? 'text-white' : 'text-slate-900'}`}>{t('match')}</h1>
<div className={`text-sm ${isDark ? 'text-white/50' : 'text-slate-500'}`}>
{matchedTotal}/{totalPairs} · <span className="text-green-400">{firstTryCorrect}</span>/<span className="text-yellow-400">{retryCorrect}</span>/<span className="text-red-400">{errors}</span>
<div className={`text-xs ${isDark ? 'text-white/50' : 'text-slate-500'}`}>
<span className="text-green-400">{firstTryCorrect}</span>{' '}
<span className="text-yellow-400">{retryCorrect}</span>{' '}
<span className="text-red-400">{errors}</span>
</div>
</div>
</div>
{/* Progress bar */}
<div className="w-full h-1.5 bg-white/10">
<div className="h-full bg-gradient-to-r from-indigo-500 to-violet-500 transition-all" style={{ width: `${(matchedTotal / Math.max(totalPairs, 1)) * 100}%` }} />
</div>
{/* Native flash overlay */}
{flashNative && (
<div className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 pointer-events-none">
@@ -199,20 +206,27 @@ export default function MatchPage() {
{/* Left: English (click to select, no sound) */}
<div className="space-y-2">
{roundItems.map(item => (
<button
<div
key={`l-${item.id}`}
onClick={() => handleLeftTap(item)}
disabled={matched.has(item.id)}
className={`w-full p-3 rounded-xl border-2 text-sm font-medium transition-all text-left ${
className={`flex items-center gap-2 p-3 rounded-xl border-2 text-sm font-medium transition-all ${
matched.has(item.id)
? 'opacity-30 border-green-400 bg-green-500/10 cursor-default'
? 'opacity-30 border-green-400 bg-green-500/10'
: selectedLeft === item.id
? (isDark ? 'border-blue-400 bg-blue-500/20 text-white' : 'border-blue-500 bg-blue-50 text-blue-900')
: (isDark ? 'border-white/20 bg-white/5 text-white hover:bg-white/10' : 'border-slate-200 bg-white text-slate-900 hover:bg-slate-50')
: (isDark ? 'border-white/20 bg-white/5 text-white' : 'border-slate-200 bg-white text-slate-900')
}`}
>
{item.question}
</button>
<button
onClick={() => handleLeftTap(item)}
disabled={matched.has(item.id)}
className="flex-1 text-left hover:opacity-80"
>
{item.question}
</button>
{!matched.has(item.id) && (
<AudioButton text={item.question} lang="en" isDark={isDark} size="sm" />
)}
</div>
))}
</div>