PairWordCard: two-step select then confirm flow

Tapping an option now highlights it (warm gold border); a
"Bestätigen" button activates once something is selected.
Answer is only evaluated on confirmation, not on tap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 13:23:42 +02:00
parent 49f9953342
commit 75bb75853e
2 changed files with 29 additions and 8 deletions

View File

@@ -337,8 +337,9 @@
border-color: #C8956A; border-color: #C8956A;
} }
.pair-option-btn:active:not(:disabled) { transform: scale(0.95); } .pair-option-btn:active:not(:disabled) { transform: scale(0.95); }
.pair-option-btn.correct { background: #3D7055; color: #fff; border-color: #3D7055; } .pair-option-btn.selected { background: #FFF0DC; border-color: #C4A85A; color: #5C3D22; }
.pair-option-btn.wrong { background: #A84040; color: #fff; border-color: #A84040; } .pair-option-btn.correct { background: #3D7055; color: #fff; border-color: #3D7055; }
.pair-option-btn.wrong { background: #A84040; color: #fff; border-color: #A84040; }
.pair-option-btn:disabled { cursor: default; } .pair-option-btn:disabled { cursor: default; }
/* ── Feedback ── */ /* ── Feedback ── */

View File

@@ -84,7 +84,8 @@ function shuffle(arr) {
} }
export default function PairWordCard({ card, onComplete }) { export default function PairWordCard({ card, onComplete }) {
const [picked, setPicked] = useState(null) const [selected, setSelected] = useState(null) // chosen but not yet confirmed
const [picked, setPicked] = useState(null) // confirmed answer
const [activeChip, setActiveChip] = useState(null) const [activeChip, setActiveChip] = useState(null)
const lang = card.lang || 'de' const lang = card.lang || 'de'
@@ -111,12 +112,17 @@ export default function PairWordCard({ card, onComplete }) {
setActiveChip(prev => prev?.id === id ? null : { id, ...entry }) setActiveChip(prev => prev?.id === id ? null : { id, ...entry })
} }
function handlePick(opt) { function handleSelect(opt) {
if (picked) return if (picked) return
setSelected(prev => prev?.id === opt.id ? null : opt)
}
function handleConfirm() {
if (!selected || picked) return
setActiveChip(null) setActiveChip(null)
setPicked(opt) setPicked(selected)
const r = opt.correct ? 'correct' : 'wrong' const r = selected.correct ? 'correct' : 'wrong'
if (opt.correct) triggerConfetti() if (selected.correct) triggerConfetti()
setTimeout(() => onComplete(r), 900) setTimeout(() => onComplete(r), 900)
} }
@@ -159,9 +165,11 @@ export default function PairWordCard({ card, onComplete }) {
if (picked) { if (picked) {
if (opt.id === picked.id) cls += opt.correct ? ' correct' : ' wrong' if (opt.id === picked.id) cls += opt.correct ? ' correct' : ' wrong'
else if (opt.correct) cls += ' correct' else if (opt.correct) cls += ' correct'
} else if (selected?.id === opt.id) {
cls += ' selected'
} }
return ( return (
<button key={opt.id} className={cls} onClick={() => handlePick(opt)} disabled={!!picked}> <button key={opt.id} className={cls} onClick={() => handleSelect(opt)} disabled={!!picked}>
{label} {label}
{picked && hint2 && opt.correct && ( {picked && hint2 && opt.correct && (
<span style={{ display: 'block', fontSize: '11px', opacity: 0.85, marginTop: 2 }}> <span style={{ display: 'block', fontSize: '11px', opacity: 0.85, marginTop: 2 }}>
@@ -181,6 +189,18 @@ export default function PairWordCard({ card, onComplete }) {
} }
</p> </p>
)} )}
{!picked && (
<div className="pair-btn-row" style={{ marginTop: 12 }}>
<button
className={`pair-btn ${selected ? 'pair-btn-primary' : 'pair-btn-locked'}`}
onClick={handleConfirm}
disabled={!selected}
>
Bestätigen
</button>
</div>
)}
</div> </div>
</div> </div>
) )