diff --git a/.gitea b/.gitea
index 70a6ee4..b1647bf 100644
--- a/.gitea
+++ b/.gitea
@@ -1 +1 @@
-@https://gitea.schwenk.online/froxxxy/bscscore/issues/9
\ No newline at end of file
+@https://gitea.schwenk.online/froxxxy/bscscore/issues/10
\ No newline at end of file
diff --git a/src/components/App.jsx b/src/components/App.jsx
index 30135ff..acbc37d 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 { Player1Step, Player2Step, Player3Step, GameTypeStep } from './NewGame.jsx';
+import { Player1Step, Player2Step, Player3Step, GameTypeStep, RaceToStep } from './NewGame.jsx';
import Modal from './Modal.jsx';
import ValidationModal from './ValidationModal.jsx';
import GameCompletionModal from './GameCompletionModal.jsx';
@@ -156,10 +156,9 @@ const App = () => {
setNewGameStep('raceTo');
};
const handleRaceToNext = (raceTo) => {
- setNewGameData(data => ({ ...data, raceTo }));
- // Finalize game creation here
- // For now, just go back to game list
- setScreen('game-list');
+ const finalData = { ...newGameData, raceTo };
+ const newId = handleCreateGame(finalData);
+ showGameDetail(newId);
setNewGameStep(null);
setNewGameData({ player1: '', player2: '', player3: '', gameType: '', raceTo: '' });
};
@@ -221,10 +220,11 @@ const App = () => {
/>
)}
{newGameStep === 'raceTo' && (
-
-
Race To Step (TODO)
-
-
+ setNewGameStep('gameType')}
+ initialValue={newGameData.raceTo}
+ />
)}
diff --git a/src/components/NewGame.jsx b/src/components/NewGame.jsx
index bcb55ed..a4689b4 100644
--- a/src/components/NewGame.jsx
+++ b/src/components/NewGame.jsx
@@ -483,4 +483,86 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }) => {
);
};
-export { Player1Step, Player2Step, Player3Step, GameTypeStep };
\ No newline at end of file
+/**
+ * Race To selection step for multi-step game creation wizard.
+ * @param {object} props
+ * @param {Function} props.onNext
+ * @param {Function} props.onCancel
+ * @param {string|number} [props.initialValue]
+ * @returns {import('preact').VNode}
+ */
+const RaceToStep = ({ onNext, onCancel, initialValue = '' }) => {
+ const [currentValue, setCurrentValue] = useState(initialValue);
+ const quickPicks = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+ const handleQuickPick = (value) => {
+ onNext(value);
+ };
+
+ const handleInputChange = (e) => {
+ setCurrentValue(e.target.value);
+ };
+
+ const handleCustomSubmit = (e) => {
+ e.preventDefault();
+ onNext(parseInt(currentValue, 10) || 0);
+ };
+
+ return (
+
+ );
+};
+
+export { Player1Step, Player2Step, Player3Step, GameTypeStep, RaceToStep };
\ No newline at end of file
diff --git a/src/components/NewGame.module.css b/src/components/NewGame.module.css
index af65ba8..63dbf15 100644
--- a/src/components/NewGame.module.css
+++ b/src/components/NewGame.module.css
@@ -215,4 +215,63 @@
.game-type-btn.selected {
background: #4a4a4a;
border-color: #777;
+}
+
+.race-to-selection {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
+ gap: 12px;
+ width: 100%;
+ margin: 16px 0;
+}
+
+.race-to-btn {
+ background: #2a2a2a;
+ border: 2px solid #333;
+ color: #fff;
+ font-size: 1.3rem;
+ font-weight: 600;
+ padding: 16px 8px;
+ border-radius: 8px;
+ cursor: pointer;
+ text-align: center;
+ transition: background 0.2s, border-color 0.2s;
+ min-height: 70px;
+}
+
+.race-to-btn:hover {
+ background: #333;
+ border-color: #555;
+}
+
+.race-to-btn.selected {
+ background: #4a4a4a;
+ border-color: #777;
+}
+
+.custom-race-to {
+ display: flex;
+ gap: 12px;
+ margin-top: 24px;
+ align-items: center;
+}
+
+.custom-race-to input {
+ flex-grow: 1;
+}
+
+.custom-race-to .arrow-btn {
+ width: 60px;
+ height: 60px;
+ font-size: 32px;
+ flex-shrink: 0;
+}
+
+.endlos-container {
+ width: 100%;
+ margin-bottom: 12px;
+}
+
+.endlos-btn {
+ width: 100%;
}
\ No newline at end of file