Refactor BSC Score to Astro, TypeScript, and modular architecture
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user