Refs #30 - Add GameTypeStep.tsx and RaceToStep.tsx under src/components/new-game - Replace inline components with imports in NewGame.tsx - Pure refactor; behavior unchanged
112 lines
4.0 KiB
TypeScript
112 lines
4.0 KiB
TypeScript
import { h } from 'preact';
|
|
import { useEffect, useState } from 'preact/hooks';
|
|
import styles from '../NewGame.module.css';
|
|
|
|
interface RaceToStepProps {
|
|
onNext: (raceTo: string | number) => void;
|
|
onCancel: () => void;
|
|
initialValue?: string | number;
|
|
gameType?: string;
|
|
}
|
|
|
|
export const RaceToStep = ({ onNext, onCancel, initialValue = '', gameType }: RaceToStepProps) => {
|
|
const quickPicks = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
const defaultValue = 5;
|
|
const [raceTo, setRaceTo] = useState<string | number>(initialValue !== '' ? initialValue : defaultValue);
|
|
|
|
useEffect(() => {
|
|
if ((initialValue === '' || initialValue === undefined) && raceTo !== defaultValue) {
|
|
setRaceTo(defaultValue);
|
|
}
|
|
if (initialValue !== '' && initialValue !== undefined && initialValue !== raceTo) {
|
|
setRaceTo(initialValue);
|
|
}
|
|
}, [gameType, initialValue, defaultValue]);
|
|
|
|
const handleQuickPick = (value: number) => {
|
|
const selected = value === 0 ? 'Infinity' : value;
|
|
setRaceTo(selected);
|
|
const raceToValue = selected === 'Infinity' ? Infinity : (parseInt(String(selected), 10) || 0);
|
|
onNext(raceToValue);
|
|
};
|
|
|
|
const handleInputChange = (e: Event) => {
|
|
const target = e.target as HTMLInputElement;
|
|
setRaceTo(target.value);
|
|
};
|
|
|
|
const handleSubmit = (e: Event) => {
|
|
e.preventDefault();
|
|
const raceToValue = raceTo === 'Infinity' ? Infinity : (parseInt(String(raceTo), 10) || 0);
|
|
onNext(raceToValue);
|
|
};
|
|
|
|
return (
|
|
<form className={styles['new-game-form']} onSubmit={handleSubmit} aria-label="Race To auswählen">
|
|
<div className={styles['screen-title']}>Race To auswählen</div>
|
|
<div className={styles['progress-indicator']} style={{ marginBottom: 24 }}>
|
|
<span className={styles['progress-dot']} />
|
|
<span className={styles['progress-dot']} />
|
|
<span className={styles['progress-dot']} />
|
|
<span className={styles['progress-dot']} />
|
|
<span className={styles['progress-dot'] + ' ' + styles['active']} />
|
|
<span className={styles['progress-dot']} />
|
|
<span className={styles['progress-dot']} />
|
|
</div>
|
|
<div className={styles['endlos-container']}>
|
|
<button
|
|
type="button"
|
|
className={`${styles['race-to-btn']} ${styles['endlos-btn']} ${raceTo === 'Infinity' ? styles.selected : ''}`}
|
|
onClick={() => handleQuickPick(0)}
|
|
>
|
|
Endlos
|
|
</button>
|
|
</div>
|
|
<div className={styles['race-to-selection']}>
|
|
{quickPicks.map(value => (
|
|
<button
|
|
key={value}
|
|
type="button"
|
|
className={`${styles['race-to-btn']} ${parseInt(String(raceTo), 10) === value ? styles.selected : ''}`}
|
|
onClick={() => handleQuickPick(value)}
|
|
>
|
|
{value}
|
|
</button>
|
|
))}
|
|
</div>
|
|
<div className={styles['custom-race-to']}>
|
|
<input
|
|
type="number"
|
|
pattern="[0-9]*"
|
|
value={raceTo}
|
|
onInput={handleInputChange}
|
|
className={styles['name-input']}
|
|
placeholder="manuelle Eingabe"
|
|
/>
|
|
</div>
|
|
<div className={styles['arrow-nav']} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 48 }}>
|
|
<button
|
|
type="button"
|
|
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' }}
|
|
>
|
|
←
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
className={styles['arrow-btn']}
|
|
aria-label="Weiter"
|
|
disabled={String(raceTo).trim() === ''}
|
|
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: String(raceTo).trim() === '' ? 0.5 : 1 }}
|
|
>
|
|
→
|
|
</button>
|
|
</div>
|
|
</form>
|
|
);
|
|
};
|
|
|
|
|