feat: complete wizard navigation for all steps

- Adds forward navigation arrows to the 'Game Type' and 'Race To' steps in the new game wizard.
- Unifies navigation logic across all five steps.
- Users can now review their selections before proceeding.

Closes #11
This commit is contained in:
Frank Schwenk
2025-06-20 10:44:27 +02:00
parent 14fd711858
commit b466dd2a0a

View File

@@ -438,14 +438,22 @@ const Player3Step = ({ playerNameHistory, onNext, onCancel, initialValue = '' })
* @returns {import('preact').VNode}
*/
const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
const [gameType, setGameType] = useState(initialValue);
const gameTypes = ['8-Ball', '9-Ball', '10-Ball', '14/1 endlos'];
const handleSelect = (gameType) => {
onNext(gameType);
const handleSelect = (selectedType) => {
setGameType(selectedType);
};
const handleSubmit = (e) => {
e.preventDefault();
if (gameType) {
onNext(gameType);
}
};
return (
<div className={styles['new-game-form']} aria-label="Spielart auswählen">
<form className={styles['new-game-form']} onSubmit={handleSubmit} aria-label="Spielart auswählen">
<div className={styles['screen-title']}>Neues Spiel Schritt 4/5</div>
<div className={styles['progress-indicator']} style={{ marginBottom: 24 }}>
<span className={styles['progress-dot']} />
@@ -459,7 +467,7 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
<button
key={type}
type="button"
className={`${styles['game-type-btn']} ${initialValue === type ? styles.selected : ''}`}
className={`${styles['game-type-btn']} ${gameType === type ? styles.selected : ''}`}
onClick={() => handleSelect(type)}
>
{type}
@@ -474,12 +482,32 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
onClick={onCancel}
style={{ fontSize: 48, width: 80, height: 80, borderRadius: '50%', background: '#222', color: '#fff', border: 'none', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', cursor: 'pointer' }}
>
{/* Unicode left arrow */}
&#8592;
</button>
{/* No "weiter" arrow, selection proceeds automatically */}
<div style={{ width: 80 }} /> {/* Placeholder to balance the flex container */}
<button
type="submit"
className={styles['arrow-btn']}
aria-label="Weiter"
disabled={!gameType}
style={{
fontSize: 48,
width: 80,
height: 80,
borderRadius: '50%',
background: '#222',
color: '#fff',
border: 'none',
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
cursor: 'pointer',
opacity: !gameType ? 0.5 : 1,
}}
>
{/* Unicode right arrow */}
&#8594;
</button>
</div>
</div>
</form>
);
};
@@ -492,24 +520,24 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
* @returns {import('preact').VNode}
*/
const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
const [currentValue, setCurrentValue] = useState(initialValue);
const [raceTo, setRaceTo] = useState(initialValue);
const quickPicks = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const handleQuickPick = (value) => {
onNext(value);
setRaceTo(value);
};
const handleInputChange = (e) => {
setCurrentValue(e.target.value);
setRaceTo(e.target.value);
};
const handleCustomSubmit = (e) => {
const handleSubmit = (e) => {
e.preventDefault();
onNext(parseInt(currentValue, 10) || 0);
onNext(parseInt(raceTo, 10) || 0);
};
return (
<form className={styles['new-game-form']} onSubmit={handleCustomSubmit} aria-label="Race To auswählen">
<form className={styles['new-game-form']} onSubmit={handleSubmit} aria-label="Race To auswählen">
<div className={styles['screen-title']}>Neues Spiel Schritt 5/5</div>
<div className={styles['progress-indicator']} style={{ marginBottom: 24 }}>
<span className={styles['progress-dot']} />
@@ -521,7 +549,7 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
<div className={styles['endlos-container']}>
<button
type="button"
className={`${styles['race-to-btn']} ${styles['endlos-btn']} ${initialValue === 0 ? styles.selected : ''}`}
className={`${styles['race-to-btn']} ${styles['endlos-btn']} ${raceTo === 0 ? styles.selected : ''}`}
onClick={() => handleQuickPick(0)}
>
Endlos
@@ -532,7 +560,7 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
<button
key={value}
type="button"
className={`${styles['race-to-btn']} ${parseInt(initialValue, 10) === value ? styles.selected : ''}`}
className={`${styles['race-to-btn']} ${parseInt(raceTo, 10) === value ? styles.selected : ''}`}
onClick={() => handleQuickPick(value)}
>
{value}
@@ -543,12 +571,11 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
<input
type="number"
pattern="[0-9]*"
value={currentValue}
value={raceTo}
onInput={handleInputChange}
className={styles['name-input']}
placeholder="manuelle Eingabe"
/>
<button type="submit" className={styles['arrow-btn']} aria-label="Bestätigen">&#10003;</button>
</div>
<div className={styles['arrow-nav']} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 48 }}>
<button
@@ -556,10 +583,20 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
className={styles['arrow-btn']}
aria-label="Zurück"
onClick={onCancel}
style={{ fontSize: 48, width: 80, height: 80, borderRadius: '50%', background: '#222', color: '#fff', border: 'none', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', cursor: 'pointer' }}
>
{/* Unicode left arrow */}
&#8592;
</button>
<div style={{ width: 80 }} />
<button
type="submit"
className={styles['arrow-btn']}
aria-label="Fertigstellen"
style={{ fontSize: 48, width: 80, height: 80, borderRadius: '50%', background: '#222', color: '#fff', border: 'none', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', cursor: 'pointer' }}
>
{/* Unicode checkmark */}
&#10003;
</button>
</div>
</form>
);