diff --git a/src/components/App.jsx b/src/components/App.jsx index 7f5c82d..469e0bd 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -2,7 +2,7 @@ import { h } from 'preact'; import { useState, useEffect, useCallback } from 'preact/hooks'; import GameList from './GameList.jsx'; import GameDetail from './GameDetail.jsx'; -import NewGame from './NewGame.jsx'; +import { Player1Step, Player2Step } from './NewGame.jsx'; import Modal from './Modal.jsx'; import ValidationModal from './ValidationModal.jsx'; import GameCompletionModal from './GameCompletionModal.jsx'; @@ -23,6 +23,8 @@ const App = () => { const [validation, setValidation] = useState({ open: false, message: '' }); const [completionModal, setCompletionModal] = useState({ open: false, game: null }); const [filter, setFilter] = useState('all'); + const [newGameStep, setNewGameStep] = useState(null); + const [newGameData, setNewGameData] = useState({ player1: '', player2: '', player3: '', gameType: '', raceTo: '' }); // Load games from localStorage on mount useEffect(() => { @@ -55,6 +57,8 @@ const App = () => { const showNewGame = useCallback(() => { setScreen('new-game'); setCurrentGameId(null); + setNewGameStep('player1'); + setNewGameData({ player1: '', player2: '', player3: '', gameType: '', raceTo: '' }); }, []); const showGameDetail = useCallback((id) => { setCurrentGameId(id); @@ -134,6 +138,39 @@ const App = () => { setValidation({ open: false, message: '' }); }, []); + // Step handlers + const handlePlayer1Next = (name) => { + setNewGameData(data => ({ ...data, player1: name })); + setNewGameStep('player2'); + }; + const handlePlayer2Next = (name) => { + setNewGameData(data => ({ ...data, player2: name })); + setNewGameStep('player3'); + }; + // Placeholder handlers for further steps + const handlePlayer3Next = (name) => { + setNewGameData(data => ({ ...data, player3: name })); + setNewGameStep('gameType'); + }; + const handleGameTypeNext = (type) => { + setNewGameData(data => ({ ...data, gameType: type })); + setNewGameStep('raceTo'); + }; + const handleRaceToNext = (raceTo) => { + setNewGameData(data => ({ ...data, raceTo })); + // Finalize game creation here + // For now, just go back to game list + setScreen('game-list'); + setNewGameStep(null); + setNewGameData({ player1: '', player2: '', player3: '', gameType: '', raceTo: '' }); + }; + + const handleCancelNewGame = useCallback(() => { + setScreen('game-list'); + setNewGameStep(null); + setNewGameData({ player1: '', player2: '', player3: '', gameType: '', raceTo: '' }); + }, []); + return (
{screen === 'game-list' && ( @@ -153,16 +190,40 @@ const App = () => { {screen === 'new-game' && (
- { - setCurrentGameId(id); - setScreen('game-detail'); - }} - initialValues={games[0]} - /> + {newGameStep === 'player1' && ( + + )} + {newGameStep === 'player2' && ( + setNewGameStep('player1')} + initialValue={newGameData.player2} + /> + )} + {newGameStep === 'player3' && ( +
+

Player 3 Step (TODO)

+ +
+ )} + {newGameStep === 'gameType' && ( +
+

Game Type Step (TODO)

+ +
+ )} + {newGameStep === 'raceTo' && ( +
+

Race To Step (TODO)

+ +
+ )}
)} diff --git a/src/components/NewGame.jsx b/src/components/NewGame.jsx index a3554e4..a989cc4 100644 --- a/src/components/NewGame.jsx +++ b/src/components/NewGame.jsx @@ -144,4 +144,143 @@ const Player1Step = ({ playerNameHistory, onNext, onCancel, initialValue = '' }) ); }; -export default Player1Step; \ No newline at end of file +/** + * Player 2 input step for multi-step game creation wizard. + * @param {object} props + * @param {string[]} props.playerNameHistory + * @param {Function} props.onNext + * @param {Function} props.onCancel + * @param {string} [props.initialValue] + * @returns {import('preact').VNode} + */ +const Player2Step = ({ playerNameHistory, onNext, onCancel, initialValue = '' }) => { + const [player2, setPlayer2] = useState(initialValue); + const [error, setError] = useState(null); + const [filteredNames, setFilteredNames] = useState(playerNameHistory); + const inputRef = useRef(null); + + useEffect(() => { + if (!player2) { + setFilteredNames(playerNameHistory); + } else { + setFilteredNames( + playerNameHistory.filter(name => + name.toLowerCase().includes(player2.toLowerCase()) + ) + ); + } + }, [player2, playerNameHistory]); + + const handleSubmit = (e) => { + e.preventDefault(); + if (!player2.trim()) { + setError('Bitte Namen für Spieler 2 eingeben'); + return; + } + setError(null); + onNext(player2.trim()); + }; + + const handleQuickPick = (name) => { + setError(null); + onNext(name); + }; + + const handleClear = () => { + setPlayer2(''); + setError(null); + if (inputRef.current) inputRef.current.focus(); + }; + + return ( +
+
Neues Spiel – Schritt 2/5
+
+ + + + + +
+
+ +
+ setPlayer2(e.target.value)} + autoFocus + autoComplete="off" + aria-label="Name Spieler 2" + style={{ fontSize: '1.2rem', minHeight: 48, marginTop: 12, marginBottom: 12, width: '100%', paddingRight: 44 }} + ref={inputRef} + /> + {player2 && ( + + )} +
+ {filteredNames.length > 0 && ( +
+ {filteredNames.slice(0, 4).map((name, idx) => ( + + ))} +
+ )} +
+ {error &&
{error}
} +
+ + +
+
+ ); +}; + +export { Player1Step, Player2Step }; \ No newline at end of file