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:
@@ -438,14 +438,22 @@ const Player3Step = ({ playerNameHistory, onNext, onCancel, initialValue = '' })
|
|||||||
* @returns {import('preact').VNode}
|
* @returns {import('preact').VNode}
|
||||||
*/
|
*/
|
||||||
const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
|
const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
|
||||||
|
const [gameType, setGameType] = useState(initialValue);
|
||||||
const gameTypes = ['8-Ball', '9-Ball', '10-Ball', '14/1 endlos'];
|
const gameTypes = ['8-Ball', '9-Ball', '10-Ball', '14/1 endlos'];
|
||||||
|
|
||||||
const handleSelect = (gameType) => {
|
const handleSelect = (selectedType) => {
|
||||||
|
setGameType(selectedType);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (gameType) {
|
||||||
onNext(gameType);
|
onNext(gameType);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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['screen-title']}>Neues Spiel – Schritt 4/5</div>
|
||||||
<div className={styles['progress-indicator']} style={{ marginBottom: 24 }}>
|
<div className={styles['progress-indicator']} style={{ marginBottom: 24 }}>
|
||||||
<span className={styles['progress-dot']} />
|
<span className={styles['progress-dot']} />
|
||||||
@@ -459,7 +467,7 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
|
|||||||
<button
|
<button
|
||||||
key={type}
|
key={type}
|
||||||
type="button"
|
type="button"
|
||||||
className={`${styles['game-type-btn']} ${initialValue === type ? styles.selected : ''}`}
|
className={`${styles['game-type-btn']} ${gameType === type ? styles.selected : ''}`}
|
||||||
onClick={() => handleSelect(type)}
|
onClick={() => handleSelect(type)}
|
||||||
>
|
>
|
||||||
{type}
|
{type}
|
||||||
@@ -474,12 +482,32 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
|
|||||||
onClick={onCancel}
|
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' }}
|
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 */}
|
||||||
←
|
←
|
||||||
</button>
|
</button>
|
||||||
{/* No "weiter" arrow, selection proceeds automatically */}
|
<button
|
||||||
<div style={{ width: 80 }} /> {/* Placeholder to balance the flex container */}
|
type="submit"
|
||||||
</div>
|
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 */}
|
||||||
|
→
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -492,24 +520,24 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
|
|||||||
* @returns {import('preact').VNode}
|
* @returns {import('preact').VNode}
|
||||||
*/
|
*/
|
||||||
const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
|
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 quickPicks = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
|
||||||
const handleQuickPick = (value) => {
|
const handleQuickPick = (value) => {
|
||||||
onNext(value);
|
setRaceTo(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInputChange = (e) => {
|
const handleInputChange = (e) => {
|
||||||
setCurrentValue(e.target.value);
|
setRaceTo(e.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCustomSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onNext(parseInt(currentValue, 10) || 0);
|
onNext(parseInt(raceTo, 10) || 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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['screen-title']}>Neues Spiel – Schritt 5/5</div>
|
||||||
<div className={styles['progress-indicator']} style={{ marginBottom: 24 }}>
|
<div className={styles['progress-indicator']} style={{ marginBottom: 24 }}>
|
||||||
<span className={styles['progress-dot']} />
|
<span className={styles['progress-dot']} />
|
||||||
@@ -521,7 +549,7 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
|
|||||||
<div className={styles['endlos-container']}>
|
<div className={styles['endlos-container']}>
|
||||||
<button
|
<button
|
||||||
type="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)}
|
onClick={() => handleQuickPick(0)}
|
||||||
>
|
>
|
||||||
Endlos
|
Endlos
|
||||||
@@ -532,7 +560,7 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
|
|||||||
<button
|
<button
|
||||||
key={value}
|
key={value}
|
||||||
type="button"
|
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)}
|
onClick={() => handleQuickPick(value)}
|
||||||
>
|
>
|
||||||
{value}
|
{value}
|
||||||
@@ -543,12 +571,11 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
pattern="[0-9]*"
|
pattern="[0-9]*"
|
||||||
value={currentValue}
|
value={raceTo}
|
||||||
onInput={handleInputChange}
|
onInput={handleInputChange}
|
||||||
className={styles['name-input']}
|
className={styles['name-input']}
|
||||||
placeholder="manuelle Eingabe"
|
placeholder="manuelle Eingabe"
|
||||||
/>
|
/>
|
||||||
<button type="submit" className={styles['arrow-btn']} aria-label="Bestätigen">✓</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles['arrow-nav']} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 48 }}>
|
<div className={styles['arrow-nav']} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 48 }}>
|
||||||
<button
|
<button
|
||||||
@@ -556,10 +583,20 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
|
|||||||
className={styles['arrow-btn']}
|
className={styles['arrow-btn']}
|
||||||
aria-label="Zurück"
|
aria-label="Zurück"
|
||||||
onClick={onCancel}
|
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 */}
|
||||||
←
|
←
|
||||||
</button>
|
</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 */}
|
||||||
|
✓
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user