fixed 5 spot component
This commit is contained in:
@@ -1,150 +1,216 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardHeader,
|
|
||||||
Grid,
|
|
||||||
Typography,
|
|
||||||
FormControl,
|
|
||||||
FormControlLabel,
|
|
||||||
Radio,
|
|
||||||
RadioGroup,
|
|
||||||
Divider
|
|
||||||
} from '@mui/material';
|
|
||||||
import { useScore, ACTIONS } from '../context/ScoreContext';
|
import { useScore, ACTIONS } from '../context/ScoreContext';
|
||||||
|
import { Button, Grid, Typography, TextField, Box } from '@mui/material';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
const GameSetup = ({ onGameStart }) => {
|
const ScoreTracker = () => {
|
||||||
const { dispatch } = useScore();
|
const { state, dispatch } = useScore();
|
||||||
const [selectedGameType, setSelectedGameType] = useState('');
|
const navigate = useNavigate();
|
||||||
const [selectedTargetFace, setSelectedTargetFace] = useState('standard');
|
|
||||||
|
|
||||||
const handleGameTypeSelect = (gameType) => {
|
const gameType = state.currentGame.gameType;
|
||||||
setSelectedGameType(gameType);
|
|
||||||
setSelectedTargetFace('standard'); // Reset to standard when game type changes
|
// Determine the number of arrows per round based on game type
|
||||||
|
const maxArrowsPerRound = gameType === '450' ? 3 : 5;
|
||||||
|
const maxScore = gameType === '450' ? 10 : 5;
|
||||||
|
const maxRounds = gameType === '450' ? 16 : 12;
|
||||||
|
|
||||||
|
const [arrowScores, setArrowScores] = useState(Array(maxArrowsPerRound).fill(''));
|
||||||
|
|
||||||
|
const handleScoreChange = (index, value) => {
|
||||||
|
const updatedScores = [...arrowScores];
|
||||||
|
updatedScores[index] = value;
|
||||||
|
setArrowScores(updatedScores);
|
||||||
};
|
};
|
||||||
|
|
||||||
const startGame = () => {
|
const handleAddRound = () => {
|
||||||
if (!selectedGameType) return;
|
const valid = arrowScores.slice(0, maxArrowsPerRound).every(score =>
|
||||||
|
(score >= 0 && score <= maxScore) || score.toUpperCase() === 'X'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
alert(`Please enter valid scores between 0-${maxScore} or X for bullseyes.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const roundArrows = arrowScores.slice(0, maxArrowsPerRound).map((score) => {
|
||||||
|
const arrowScore = score.toUpperCase() === 'X' ? maxScore : parseInt(score, 10);
|
||||||
|
return {
|
||||||
|
score: arrowScore,
|
||||||
|
isBullseye: score.toUpperCase() === 'X',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const roundTotal = roundArrows.reduce((sum, arrow) => sum + arrow.score, 0);
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.START_GAME,
|
type: ACTIONS.ADD_ROUND,
|
||||||
payload: {
|
payload: {
|
||||||
gameType: selectedGameType,
|
roundIndex: state.currentGame.rounds.length,
|
||||||
isLeague: false,
|
arrows: roundArrows,
|
||||||
targetFace: selectedTargetFace
|
total: roundTotal
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
onGameStart();
|
|
||||||
|
setArrowScores(Array(maxArrowsPerRound).fill(''));
|
||||||
|
|
||||||
|
if (state.currentGame.rounds.length >= maxRounds - 1) {
|
||||||
|
navigate('/summary');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine if we should show target face options
|
const handleMainMenu = () => {
|
||||||
const showTargetFaceOptions = selectedGameType !== '';
|
dispatch({ type: ACTIONS.RESET_GAME });
|
||||||
|
navigate('/');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={3} justifyContent="center" alignItems="center" style={{ minHeight: '80vh' }}>
|
<Grid container spacing={2} justifyContent="center">
|
||||||
<Grid item xs={12} sm={8} md={6}>
|
{/* Main Menu Button */}
|
||||||
<Card>
|
<Box
|
||||||
<CardHeader
|
sx={{
|
||||||
title="Start New Game"
|
position: 'absolute',
|
||||||
titleTypographyProps={{ align: 'center' }}
|
top: 16,
|
||||||
/>
|
left: 16,
|
||||||
<CardContent>
|
}}
|
||||||
<Grid container spacing={3}>
|
>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
onClick={handleMainMenu}
|
||||||
|
>
|
||||||
|
Main Menu
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="body1" align="center" gutterBottom>
|
<Typography variant="h5" align="center" gutterBottom>
|
||||||
Select your game type:
|
{gameType} Round - Round {state.currentGame.rounds.length + 1}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
|
||||||
|
{/* Score input section */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 1,
|
||||||
|
mb: 2
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Array.from({ length: maxArrowsPerRound }).map((_, index) => (
|
||||||
|
<TextField
|
||||||
|
key={index}
|
||||||
|
value={arrowScores[index]}
|
||||||
|
onChange={(e) => handleScoreChange(index, e.target.value)}
|
||||||
|
placeholder="0"
|
||||||
|
size="small"
|
||||||
|
sx={{
|
||||||
|
width: '60px',
|
||||||
|
'& .MuiInputBase-input': {
|
||||||
|
padding: '8px',
|
||||||
|
textAlign: 'center'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
inputProps={{
|
||||||
|
maxLength: 1,
|
||||||
|
style: { textAlign: 'center' }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Score buttons */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 1,
|
||||||
|
mb: 2
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Array.from({ length: maxScore + 1 }).map((_, i) => (
|
||||||
|
<Button
|
||||||
|
key={i}
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
sx={{ minWidth: '40px', height: '40px' }}
|
||||||
|
onClick={() => {
|
||||||
|
const emptyIndex = arrowScores.findIndex(score => score === '');
|
||||||
|
if (emptyIndex >= 0 && emptyIndex < maxArrowsPerRound) {
|
||||||
|
handleScoreChange(emptyIndex, i.toString());
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
sx={{ minWidth: '40px', height: '40px' }}
|
||||||
|
onClick={() => {
|
||||||
|
const emptyIndex = arrowScores.findIndex(score => score === '');
|
||||||
|
if (emptyIndex >= 0 && emptyIndex < maxArrowsPerRound) {
|
||||||
|
handleScoreChange(emptyIndex, 'X');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Control buttons */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'center', gap: 2 }}>
|
||||||
<Button
|
<Button
|
||||||
fullWidth
|
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
size={selectedGameType === '450' ? "large" : "medium"}
|
onClick={handleAddRound}
|
||||||
onClick={() => handleGameTypeSelect('450')}
|
disabled={!arrowScores.slice(0, maxArrowsPerRound).every(score => score !== '')}
|
||||||
style={{
|
|
||||||
backgroundColor: selectedGameType === '450' ? undefined : '#1976d2',
|
|
||||||
boxShadow: selectedGameType === '450' ? '0 0 10px #1976d2' : undefined
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
450 Round
|
Add Round
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
|
||||||
<Grid item xs={6}>
|
|
||||||
<Button
|
<Button
|
||||||
fullWidth
|
variant="outlined"
|
||||||
variant="contained"
|
onClick={() => setArrowScores(Array(maxArrowsPerRound).fill(''))}
|
||||||
color="secondary"
|
|
||||||
size={selectedGameType === '300' ? "large" : "medium"}
|
|
||||||
onClick={() => handleGameTypeSelect('300')}
|
|
||||||
style={{
|
|
||||||
backgroundColor: selectedGameType === '300' ? undefined : '#9c27b0',
|
|
||||||
boxShadow: selectedGameType === '300' ? '0 0 10px #9c27b0' : undefined
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
300 Round
|
Clear
|
||||||
</Button>
|
</Button>
|
||||||
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{showTargetFaceOptions && (
|
{/* Scores display */}
|
||||||
<>
|
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Divider style={{ margin: '16px 0' }} />
|
<Typography variant="h6" align="center">
|
||||||
<Typography variant="body1" align="center" gutterBottom>
|
Total Score: {state.currentGame.totalScore} |
|
||||||
Select your target face:
|
Bullseyes: {state.currentGame.totalBullseyes}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
|
||||||
<FormControl component="fieldset">
|
|
||||||
<RadioGroup
|
|
||||||
row
|
|
||||||
name="targetFace"
|
|
||||||
value={selectedTargetFace}
|
|
||||||
onChange={(e) => setSelectedTargetFace(e.target.value)}
|
|
||||||
>
|
|
||||||
<FormControlLabel
|
|
||||||
value="standard"
|
|
||||||
control={<Radio />}
|
|
||||||
label="Standard"
|
|
||||||
/>
|
|
||||||
{selectedGameType === '300' && (
|
|
||||||
<FormControlLabel
|
|
||||||
value="5-spot"
|
|
||||||
control={<Radio />}
|
|
||||||
label="5-Spot"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{selectedGameType === '450' && (
|
|
||||||
<FormControlLabel
|
|
||||||
value="3-spot"
|
|
||||||
control={<Radio />}
|
|
||||||
label="3-Spot"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</RadioGroup>
|
|
||||||
</FormControl>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={12} style={{ marginTop: '16px' }}>
|
{/* Round history */}
|
||||||
<Button
|
<Grid item xs={12}>
|
||||||
fullWidth
|
<Box sx={{ maxHeight: '200px', overflow: 'auto' }}>
|
||||||
variant="contained"
|
{state.currentGame.rounds.length > 0 ? (
|
||||||
color="success"
|
state.currentGame.rounds.map((round, roundIndex) => (
|
||||||
size="large"
|
<Typography key={roundIndex} variant="body2" align="center">
|
||||||
onClick={startGame}
|
Round {roundIndex + 1}: {round.arrows.map(arrow => arrow.score).join(', ')}
|
||||||
>
|
(Total: {round.total}, Bullseyes: {round.bullseyes})
|
||||||
Start Game
|
</Typography>
|
||||||
</Button>
|
))
|
||||||
</Grid>
|
) : (
|
||||||
</>
|
<Typography variant="body2" align="center">
|
||||||
|
No rounds played yet.
|
||||||
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Box>
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GameSetup;
|
export default ScoreTracker;
|
||||||
|
|
||||||
|
|||||||
@@ -1,231 +1,162 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardHeader,
|
||||||
|
FormControl,
|
||||||
|
FormControlLabel,
|
||||||
|
RadioGroup,
|
||||||
|
Radio,
|
||||||
|
Grid,
|
||||||
|
Typography,
|
||||||
|
Select,
|
||||||
|
MenuItem
|
||||||
|
} from '@mui/material';
|
||||||
import { useScore, ACTIONS } from '../context/ScoreContext';
|
import { useScore, ACTIONS } from '../context/ScoreContext';
|
||||||
import { Button, Grid, Typography, TextField, Box } from '@mui/material';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
|
|
||||||
const ScoreTracker = () => {
|
const GameSetup = ({ onGameStart }) => {
|
||||||
const { state, dispatch } = useScore();
|
const { dispatch } = useScore();
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const gameType = state.currentGame.gameType;
|
const [selectedGameType, setSelectedGameType] = useState('');
|
||||||
const isLeague = state.currentGame.isLeague; // Check if it's a league game
|
const [isLeague, setIsLeague] = useState(false); // This tracks if it's a league game
|
||||||
const maxArrowsPerRound = gameType === '450' ? 3 : 5;
|
const [selectedTargetFace, setSelectedTargetFace] = useState('single'); // Assuming single as default target face
|
||||||
const maxScore = gameType === '450' ? 10 : 5;
|
|
||||||
const maxRounds = gameType === '450' ? 16 : 12;
|
|
||||||
|
|
||||||
const [arrowScores, setArrowScores] = useState(Array(maxArrowsPerRound).fill(''));
|
// Log isLeague to verify if it changes correctly
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("Game mode isLeague:", isLeague); // Check this in the console
|
||||||
|
}, [isLeague]);
|
||||||
|
|
||||||
const handleScoreChange = (index, value) => {
|
const handleGameModeChange = (event) => {
|
||||||
const updatedScores = [...arrowScores];
|
const leagueMode = event.target.value === "league";
|
||||||
updatedScores[index] = value;
|
setIsLeague(leagueMode); // Update isLeague based on user selection
|
||||||
setArrowScores(updatedScores);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddRound = () => {
|
const handleTargetFaceChange = (event) => {
|
||||||
const valid = arrowScores.slice(0, maxArrowsPerRound).every(score =>
|
setSelectedTargetFace(event.target.value);
|
||||||
(score >= 0 && score <= maxScore) || score.toUpperCase() === 'X'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!valid) {
|
|
||||||
alert(`Please enter valid scores between 0-${maxScore} or X for bullseyes.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roundArrows = arrowScores.slice(0, maxArrowsPerRound).map((score) => {
|
|
||||||
const arrowScore = score.toUpperCase() === 'X' ? maxScore : parseInt(score, 10);
|
|
||||||
return {
|
|
||||||
score: arrowScore,
|
|
||||||
isBullseye: score.toUpperCase() === 'X',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const startGame = () => {
|
||||||
|
if (!selectedGameType) return;
|
||||||
|
|
||||||
|
// Log the values to ensure they're correct
|
||||||
|
console.log("Starting game with settings:", {
|
||||||
|
gameType: selectedGameType,
|
||||||
|
isLeague: isLeague,
|
||||||
|
targetFace: selectedTargetFace
|
||||||
});
|
});
|
||||||
|
|
||||||
const roundTotal = roundArrows.reduce((sum, arrow) => sum + arrow.score, 0);
|
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.ADD_ROUND,
|
type: ACTIONS.START_GAME,
|
||||||
payload: {
|
payload: {
|
||||||
roundIndex: state.currentGame.rounds.length,
|
gameType: selectedGameType,
|
||||||
arrows: roundArrows,
|
isLeague: isLeague, // Pass the league/practice mode correctly
|
||||||
total: roundTotal
|
targetFace: selectedTargetFace
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
setArrowScores(Array(maxArrowsPerRound).fill(''));
|
|
||||||
|
|
||||||
if (state.currentGame.rounds.length >= maxRounds - 1) {
|
|
||||||
navigate('/summary');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleMainMenu = () => {
|
|
||||||
dispatch({ type: ACTIONS.RESET_GAME });
|
|
||||||
navigate('/');
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleGameStart = (gameType, isLeague) => {
|
|
||||||
// Dispatch the action to start a new round with the correct game type and isLeague flag
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.START_NEW_ROUND,
|
|
||||||
payload: {
|
|
||||||
gameType, // '450' or '300'
|
|
||||||
isLeague // true for league games, false for practice games
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
navigate('/score-tracker'); // Navigate directly to the score tracker
|
onGameStart();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={2} justifyContent="center">
|
<Grid container spacing={3} justifyContent="center" alignItems="center" style={{ minHeight: '80vh' }}>
|
||||||
{/* Main Menu Button */}
|
<Grid item xs={12} sm={8} md={6}>
|
||||||
<Box
|
<Card>
|
||||||
sx={{
|
<CardHeader
|
||||||
position: 'absolute',
|
title="Start New Game"
|
||||||
top: 16,
|
titleTypographyProps={{ align: 'center' }}
|
||||||
left: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
onClick={handleMainMenu}
|
|
||||||
>
|
|
||||||
Main Menu
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="h5" align="center" gutterBottom>
|
|
||||||
{gameType} Round - Round {state.currentGame.rounds.length + 1}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="subtitle1" align="center" gutterBottom>
|
|
||||||
{isLeague ? 'League Game' : 'Practice Game'} {/* Display whether it's a league or practice game */}
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Score input section */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
gap: 1,
|
|
||||||
mb: 2
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Array.from({ length: maxArrowsPerRound }).map((_, index) => (
|
|
||||||
<TextField
|
|
||||||
key={index}
|
|
||||||
value={arrowScores[index]}
|
|
||||||
onChange={(e) => handleScoreChange(index, e.target.value)}
|
|
||||||
placeholder="0"
|
|
||||||
size="small"
|
|
||||||
sx={{
|
|
||||||
width: '60px',
|
|
||||||
'& .MuiInputBase-input': {
|
|
||||||
padding: '8px',
|
|
||||||
textAlign: 'center'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
inputProps={{
|
|
||||||
maxLength: 1,
|
|
||||||
style: { textAlign: 'center' }
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
))}
|
<CardContent>
|
||||||
</Box>
|
<Grid container spacing={3}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" align="center" gutterBottom>
|
||||||
|
Select your game type:
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
variant="contained"
|
||||||
|
color={selectedGameType === '450' ? 'primary' : 'default'}
|
||||||
|
size="large"
|
||||||
|
onClick={() => setSelectedGameType('450')}
|
||||||
|
>
|
||||||
|
450 Round
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
variant="contained"
|
||||||
|
color={selectedGameType === '300' ? 'secondary' : 'default'}
|
||||||
|
size="large"
|
||||||
|
onClick={() => setSelectedGameType('300')}
|
||||||
|
>
|
||||||
|
300 Round
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* Score buttons */}
|
{/* Select League or Practice Mode */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Box
|
<FormControl component="fieldset" fullWidth>
|
||||||
sx={{
|
<Typography variant="body1" align="center" gutterBottom>
|
||||||
display: 'flex',
|
Select game mode:
|
||||||
flexWrap: 'wrap',
|
</Typography>
|
||||||
justifyContent: 'center',
|
<RadioGroup
|
||||||
gap: 1,
|
row
|
||||||
mb: 2
|
name="gameMode"
|
||||||
}}
|
value={isLeague ? "league" : "practice"} // Display correct mode
|
||||||
|
onChange={handleGameModeChange}
|
||||||
>
|
>
|
||||||
{Array.from({ length: maxScore + 1 }).map((_, i) => (
|
<FormControlLabel
|
||||||
<Button
|
value="practice"
|
||||||
key={i}
|
control={<Radio />}
|
||||||
variant="outlined"
|
label="Practice"
|
||||||
size="small"
|
/>
|
||||||
sx={{ minWidth: '40px', height: '40px' }}
|
<FormControlLabel
|
||||||
onClick={() => {
|
value="league"
|
||||||
const emptyIndex = arrowScores.findIndex(score => score === '');
|
control={<Radio />}
|
||||||
if (emptyIndex >= 0 && emptyIndex < maxArrowsPerRound) {
|
label="League"
|
||||||
handleScoreChange(emptyIndex, i.toString());
|
/>
|
||||||
}
|
</RadioGroup>
|
||||||
}}
|
</FormControl>
|
||||||
>
|
|
||||||
{i}
|
|
||||||
</Button>
|
|
||||||
))}
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
size="small"
|
|
||||||
sx={{ minWidth: '40px', height: '40px' }}
|
|
||||||
onClick={() => {
|
|
||||||
const emptyIndex = arrowScores.findIndex(score => score === '');
|
|
||||||
if (emptyIndex >= 0 && emptyIndex < maxArrowsPerRound) {
|
|
||||||
handleScoreChange(emptyIndex, 'X');
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
X
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* Control buttons */}
|
{/* Target face selection */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<Typography variant="body1" align="center" gutterBottom>
|
||||||
|
Select target face:
|
||||||
|
</Typography>
|
||||||
|
<Select
|
||||||
|
value={selectedTargetFace}
|
||||||
|
onChange={handleTargetFaceChange}
|
||||||
|
>
|
||||||
|
<MenuItem value="single">Single Spot</MenuItem>
|
||||||
|
<MenuItem value="five">Five Spot</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Start Game Button */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'center', gap: 2 }}>
|
|
||||||
<Button
|
<Button
|
||||||
|
fullWidth
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={handleAddRound}
|
size="large"
|
||||||
disabled={!arrowScores.slice(0, maxArrowsPerRound).every(score => score !== '')}
|
onClick={startGame}
|
||||||
|
disabled={!selectedGameType} // Disable button if no game type selected
|
||||||
>
|
>
|
||||||
Add Round
|
Start Game
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => setArrowScores(Array(maxArrowsPerRound).fill(''))}
|
|
||||||
>
|
|
||||||
Clear
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* Scores display */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="h6" align="center">
|
|
||||||
Total Score: {state.currentGame.totalScore} |
|
|
||||||
Bullseyes: {state.currentGame.totalBullseyes}
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</CardContent>
|
||||||
{/* Round history */}
|
</Card>
|
||||||
<Grid item xs={12}>
|
|
||||||
<Box sx={{ maxHeight: '200px', overflow: 'auto' }}>
|
|
||||||
{state.currentGame.rounds.length > 0 ? (
|
|
||||||
state.currentGame.rounds.map((round, roundIndex) => (
|
|
||||||
<Typography key={roundIndex} variant="body2" align="center">
|
|
||||||
Round {roundIndex + 1}: {round.arrows.map(arrow => arrow.score).join(', ')}
|
|
||||||
(Total: {round.total}, Bullseyes: {round.bullseyes})
|
|
||||||
</Typography>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<Typography variant="body2" align="center">
|
|
||||||
No rounds played yet.
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ScoreTracker;
|
export default GameSetup;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user