Added menu

This commit is contained in:
Administrator
2025-02-14 22:08:11 -05:00
parent c140cb22b0
commit d7e3fe3b2b
4 changed files with 319 additions and 192 deletions

View File

@@ -1,58 +1,37 @@
import React from 'react';
import { useScore } from '../context/ScoreContext';
import { Button, Grid, Typography, Box } from '@mui/material';
import { useScore, ACTIONS } from '../context/ScoreContext';
import { useNavigate } from 'react-router-dom';
import { Button, Typography, Box, Grid } from '@mui/material';
const GameSummary = () => {
const { state } = useScore();
const { state, dispatch } = useScore();
const navigate = useNavigate();
const handleNewGame = () => {
const handleReturnToMenu = () => {
dispatch({ type: ACTIONS.RESET_GAME });
navigate('/');
};
return (
<>
{/* Main Menu Button */}
<Box
sx={{
position: 'absolute',
top: 16,
left: 16,
}}
>
<Button variant="outlined" onClick={handleNewGame}>
Main Menu
</Button>
</Box>
<Grid container spacing={2} justifyContent="center">
<Grid item xs={12}>
<Typography variant="h4" align="center" gutterBottom>
<Box sx={{ p: 4 }}>
<Typography variant="h4" gutterBottom align="center">
Game Summary
</Typography>
</Grid>
{/* Total score */}
<Grid item xs={12}>
<Typography variant="h6" align="center">
Total Score: {state.currentGame.totalScore}
</Typography>
<Typography variant="h6" align="center">
Total Bullseyes: {state.currentGame.totalBullseyes}
</Typography>
</Grid>
{/* Your existing summary content here */}
{/* New game button */}
<Grid item xs={12} align="center">
<Button variant="contained" onClick={handleNewGame}>
Start New Game
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'center' }}>
<Button
variant="contained"
color="primary"
onClick={handleReturnToMenu}
sx={{ minWidth: 200 }}
>
Return to Main Menu
</Button>
</Grid>
</Grid>
</>
</Box>
</Box>
);
};
export default GameSummary;

View File

@@ -1,12 +1,11 @@
// src/components/ScoreTracker.js
import React, { useState } from 'react';
import { useScore, ACTIONS } from '../context/ScoreContext';
import { Button, Grid, Typography, TextField, Box } from '@mui/material';
import { useNavigate } from 'react-router-dom'; // <-- Add this import
import { useNavigate } from 'react-router-dom';
const ScoreTracker = () => {
const { state, dispatch } = useScore();
const navigate = useNavigate(); // <-- Define the navigate hook
const navigate = useNavigate();
const gameType = state.currentGame.gameType;
const maxArrowsPerRound = gameType === '450' ? 3 : 5;
const maxScore = gameType === '450' ? 10 : 5;
@@ -14,36 +13,30 @@ const ScoreTracker = () => {
const [arrowScores, setArrowScores] = useState(Array(maxArrowsPerRound).fill(''));
const handleMainMenu = () => {
if (window.confirm('Are you sure you want to return to the main menu? Current game progress will be lost.')) {
dispatch({ type: ACTIONS.RESET_GAME });
navigate('/');
}
};
const handleScoreChange = (index, value) => {
const updatedScores = [...arrowScores];
updatedScores[index] = value;
setArrowScores(updatedScores);
};
// Handle Add Round, Game Completion, etc.
const handleGameEnd = () => {
// Navigate to the summary page after the game ends
navigate('/summary');
};
// Handle adding a round
const handleAddRound = () => {
// Check if the max number of rounds is reached
if (state.currentGame.rounds.length >= maxRounds) {
navigate('/summary'); // Navigate to summary page when max rounds are reached
return;
}
// Validate Scores
if (state.currentGame.rounds.length >= maxRounds - 1) { // Check if this is the last round
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;
}
// Add arrows to the current round
const roundArrows = arrowScores.slice(0, maxArrowsPerRound).map((score) => {
const arrowScore = score.toUpperCase() === 'X' ? maxScore : parseInt(score, 10);
return {
@@ -60,147 +53,58 @@ const ScoreTracker = () => {
},
});
setArrowScores(['', '', '', '', '']);
navigate('/summary');
return;
}
// Regular round handling
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',
};
});
dispatch({
type: ACTIONS.ADD_ROUND,
payload: {
roundIndex: state.currentGame.rounds.length,
arrows: roundArrows,
},
});
setArrowScores(Array(maxArrowsPerRound).fill(''));
};
return (
<Grid container spacing={2} justifyContent="center">
<Grid item xs={12}>
<Typography variant="h5" align="center" gutterBottom>
{gameType} Round - Round {state.currentGame.rounds.length + 1}
</Typography>
</Grid>
{/* Compact 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>
))}
<Box sx={{ position: 'relative', width: '100%', p: 2 }}>
<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');
}
onClick={handleMainMenu}
sx={{
position: 'absolute',
left: 16,
top: 16,
}}
>
X
</Button>
<Button
variant="outlined"
onClick={() => navigate('/')}
>
Main Menu
</Button>
</Box>
</Grid>
{/* Control buttons */}
<Grid item xs={12}>
<Box sx={{ display: 'flex', justifyContent: 'center', gap: 2 }}>
<Button
variant="contained"
color="primary"
onClick={handleAddRound}
disabled={!arrowScores.slice(0, maxArrowsPerRound).every(score => score !== '')}
>
Add Round
</Button>
<Button
variant="outlined"
onClick={() => setArrowScores(['', '', '', '', ''])}
>
Clear
</Button>
<Grid container spacing={2} justifyContent="center">
{/* ... rest of your JSX ... */}
</Grid>
</Box>
</Grid>
{/* Scores display */}
<Grid item xs={12}>
<Typography variant="h6" align="center">
Total Score: {state.currentGame.totalScore} |
Bullseyes: {state.currentGame.totalBullseyes}
</Typography>
</Grid>
{/* Round history */}
<Grid item xs={12}>
<Box sx={{ maxHeight: '200px', overflow: 'auto' }}>
{state.currentGame && state.currentGame.rounds && state.currentGame.rounds.length > 0 ? (
state.currentGame.rounds.map((round, roundIndex) => (
<Typography key={roundIndex} variant="body2" align="center">
Round {roundIndex + 1}: {round.arrows ? round.arrows.join(', ') : 'No arrows'}
(Total: {round.total || 0}, Bullseyes: {round.bullseyes || 0})
</Typography>
))
) : (
<Typography variant="body2" align="center">
No rounds played yet.
</Typography>
)}
</Box>
</Grid>
</Grid>
);
};
export default ScoreTracker;

View File

@@ -0,0 +1,207 @@
import React, { useState } from 'react';
import { useScore, ACTIONS } from '../context/ScoreContext';
import { Button, Grid, Typography, TextField, Box } from '@mui/material';
import { useNavigate } from 'react-router-dom';
const ScoreTracker = () => {
const { state, dispatch } = useScore();
const navigate = useNavigate();
const gameType = state.currentGame.gameType;
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 handleMainMenu = () => {
if (window.confirm('Are you sure you want to return to the main menu? Current game progress will be lost.')) {
dispatch({ type: ACTIONS.RESET_GAME });
navigate('/');
}
};
const handleScoreChange = (index, value) => {
const updatedScores = [...arrowScores];
updatedScores[index] = value;
setArrowScores(updatedScores);
};
const handleAddRound = () => {
if (state.currentGame.rounds.length >= maxRounds - 1) { // Check if this is the last round
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',
};
});
dispatch({
type: ACTIONS.ADD_ROUND,
payload: {
roundIndex: state.currentGame.rounds.length,
arrows: roundArrows,
},
});
setArrowScores(Array(maxArrowsPerRound).fill(''));
};
return (
<Box sx={{ position: 'relative', width: '100%', p: 2 }}>
{/* Menu Button - Now positioned at top left */}
<Button
variant="outlined"
onClick={() => navigate('/')}
sx={{
position: 'absolute',
left: 16,
top: 16,
}}
>
Main Menu
</Button>
<Grid container spacing={2} justifyContent="center">
<Grid item xs={12}>
<Typography variant="h5" align="center" gutterBottom>
{gameType} Round - Round {state.currentGame.rounds.length + 1}
</Typography>
</Grid>
{/* Compact 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
variant="contained"
color="primary"
onClick={handleAddRound}
disabled={!arrowScores.slice(0, maxArrowsPerRound).every(score => score !== '')}
>
Add Round
</Button>
<Button
variant="outlined"
onClick={() => setArrowScores(Array(maxArrowsPerRound).fill(''))}
>
Clear
</Button>
</Box>
</Grid>
{/* Scores display */}
<Grid item xs={12}>
<Typography variant="h6" align="center">
Total Score: {state.currentGame.totalScore} |
Bullseyes: {state.currentGame.totalBullseyes}
</Typography>
</Grid>
{/* Round history */}
<Grid item xs={12}>
<Box>
{state.currentGame && state.currentGame.rounds && 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.isBullseye ? 'X' : arrow.score).join(', ')}
(Total: {round.total || 0}, Bullseyes: {round.bullseyes || 0})
</Typography>
))
) : (
<Typography variant="body2" align="center">
No rounds played yet.
</Typography>
)}
</Box>
</Grid>
</Grid>
</Box>
);
};
export default ScoreTracker;

37
asc/src/components/rm Normal file
View File

@@ -0,0 +1,37 @@
import React from 'react';
import { useScore, ACTIONS } from '../context/ScoreContext';
import { useNavigate } from 'react-router-dom';
import { Button, Typography, Box, Grid } from '@mui/material';
const GameSummary = () => {
const { state, dispatch } = useScore();
const navigate = useNavigate();
const handleReturnToMenu = () => {
dispatch({ type: ACTIONS.RESET_GAME });
navigate('/');
};
return (
<Box sx={{ p: 4 }}>
<Typography variant="h4" gutterBottom align="center">
Game Summary
</Typography>
{/* Your existing summary content here */}
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'center' }}>
<Button
variant="contained"
color="primary"
onClick={handleReturnToMenu}
sx={{ minWidth: 200 }}
>
Return to Main Menu
</Button>
</Box>
</Box>
);
};
export default GameSummary;