Refactor BSC Score to Astro, TypeScript, and modular architecture

This commit is contained in:
Cursor Agent
2025-06-24 11:44:19 +00:00
parent bcf793b9e3
commit 6f626c9977
30 changed files with 1836 additions and 497 deletions
@@ -0,0 +1,46 @@
import { h } from 'preact';
import { Screen } from '../ui/Layout';
import GameDetail from '../GameDetail';
import type { Game, EndlosGame } from '../../types/game';
interface GameDetailScreenProps {
game?: Game;
onUpdateScore: (player: number, change: number) => void;
onFinishGame: () => void;
onUpdateGame: (game: EndlosGame) => void;
onUndo: () => void;
onForfeit: () => void;
onBack: () => void;
}
export default function GameDetailScreen({
game,
onUpdateScore,
onFinishGame,
onUpdateGame,
onUndo,
onForfeit,
onBack,
}: GameDetailScreenProps) {
if (!game) {
return (
<Screen>
<div>Game not found</div>
</Screen>
);
}
return (
<Screen>
<GameDetail
game={game}
onUpdateScore={onUpdateScore}
onFinishGame={onFinishGame}
onUpdateGame={onUpdateGame}
onUndo={onUndo}
onForfeit={onForfeit}
onBack={onBack}
/>
</Screen>
);
}
+45
View File
@@ -0,0 +1,45 @@
import { h } from 'preact';
import { Button } from '../ui/Button';
import { Screen } from '../ui/Layout';
import GameList from '../GameList';
import type { Game, GameFilter } from '../../types/game';
interface GameListScreenProps {
games: Game[];
filter: GameFilter;
onFilterChange: (filter: GameFilter) => void;
onShowGameDetail: (gameId: number) => void;
onDeleteGame: (gameId: number) => void;
onShowNewGame: () => void;
}
export default function GameListScreen({
games,
filter,
onFilterChange,
onShowGameDetail,
onDeleteGame,
onShowNewGame,
}: GameListScreenProps) {
return (
<Screen>
<Button
variant="primary"
size="large"
onClick={onShowNewGame}
aria-label="Neues Spiel starten"
style={{ width: '100%', marginBottom: '24px' }}
>
+ Neues Spiel
</Button>
<GameList
games={games}
filter={filter}
onShowGameDetail={onShowGameDetail}
onDeleteGame={onDeleteGame}
setFilter={onFilterChange}
/>
</Screen>
);
}
+121
View File
@@ -0,0 +1,121 @@
import { h } from 'preact';
import { Screen } from '../ui/Layout';
import { Player1Step, Player2Step, Player3Step, GameTypeStep, RaceToStep } from '../NewGame';
import type { NewGameStep, NewGameData } from '../../types/game';
interface NewGameScreenProps {
step: NewGameStep;
data: NewGameData;
playerHistory: string[];
onStepChange: (step: NewGameStep) => void;
onDataChange: (data: Partial<NewGameData>) => void;
onCreateGame: (data: NewGameData) => void;
onCancel: () => void;
onShowValidation: (message: string) => void;
}
export default function NewGameScreen({
step,
data,
playerHistory,
onStepChange,
onDataChange,
onCreateGame,
onCancel,
onShowValidation,
}: NewGameScreenProps) {
const handlePlayer1Next = (name: string) => {
onDataChange({ player1: name });
onStepChange('player2');
};
const handlePlayer2Next = (name: string) => {
onDataChange({ player2: name });
onStepChange('player3');
};
const handlePlayer3Next = (name: string) => {
onDataChange({ player3: name });
onStepChange('gameType');
};
const handleGameTypeNext = (type: string) => {
onDataChange({
gameType: type as any, // Type assertion for now, could be improved with proper validation
raceTo: type === '14/1 endlos' ? '150' : '50'
});
onStepChange('raceTo');
};
const handleRaceToNext = (raceTo: string) => {
const finalData = { ...data, raceTo };
onCreateGame(finalData);
};
const handleStepBack = () => {
switch (step) {
case 'player2':
onStepChange('player1');
break;
case 'player3':
onStepChange('player2');
break;
case 'gameType':
onStepChange('player3');
break;
case 'raceTo':
onStepChange('gameType');
break;
default:
onCancel();
}
};
return (
<Screen>
{step === 'player1' && (
<Player1Step
playerNameHistory={playerHistory}
onNext={handlePlayer1Next}
onCancel={onCancel}
initialValue={data.player1}
/>
)}
{step === 'player2' && (
<Player2Step
playerNameHistory={playerHistory}
onNext={handlePlayer2Next}
onCancel={handleStepBack}
initialValue={data.player2}
/>
)}
{step === 'player3' && (
<Player3Step
playerNameHistory={playerHistory}
onNext={handlePlayer3Next}
onCancel={handleStepBack}
initialValue={data.player3}
/>
)}
{step === 'gameType' && (
<GameTypeStep
onNext={handleGameTypeNext}
onCancel={handleStepBack}
initialValue={data.gameType}
/>
)}
{step === 'raceTo' && (
<RaceToStep
onNext={handleRaceToNext}
onCancel={handleStepBack}
initialValue={data.raceTo}
gameType={data.gameType}
/>
)}
</Screen>
);
}