fixed navigation and updated buttons

This commit is contained in:
corey@blaishome.online
2025-03-18 23:42:30 -04:00
parent f3c86d7d11
commit 19e6336692
7 changed files with 963 additions and 391 deletions

View File

@@ -1,156 +1,319 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import {
Button,
Card,
CardContent,
CardHeader,
FormControl,
FormControlLabel,
RadioGroup,
Radio,
Grid,
Typography,
Select,
MenuItem
Box,
Paper,
IconButton,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Divider,
ButtonGroup
} from '@mui/material';
import { Remove } from '@mui/icons-material';
import { useScore, ACTIONS } from '../context/ScoreContext';
const GameSetup = ({ onGameStart }) => {
const { dispatch } = useScore();
const [selectedGameType, setSelectedGameType] = useState('');
const [isLeague, setIsLeague] = useState(false); // This tracks if it's a league game
const [selectedTargetFace, setSelectedTargetFace] = useState('single'); // Assuming single as default target face
// Log isLeague to verify if it changes correctly
const ScoreTracker = () => {
const { state, dispatch } = useScore();
const navigate = useNavigate();
// Local state for the current end
const [currentEnd, setCurrentEnd] = useState([]);
// Check if we have an active game, if not redirect to setup
useEffect(() => {
console.log("Game mode isLeague:", isLeague); // Check this in the console
}, [isLeague]);
const handleGameModeChange = (event) => {
const leagueMode = event.target.value === "league";
setIsLeague(leagueMode); // Update isLeague based on user selection
if (!state.currentGame || !state.currentGame.gameType) {
navigate('/');
}
}, [state.currentGame, navigate]);
// Handle adding an arrow score
const handleAddArrow = (score) => {
// Add to current end
setCurrentEnd([...currentEnd, score]);
};
const handleTargetFaceChange = (event) => {
setSelectedTargetFace(event.target.value);
// Handle removing the last arrow
const handleRemoveArrow = () => {
if (currentEnd.length > 0) {
const newEnd = [...currentEnd];
newEnd.pop();
setCurrentEnd(newEnd);
}
};
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
});
// Calculate total for current end
const calculateEndTotal = (arrows) => {
return arrows.reduce((total, arrow) => {
if (arrow.toUpperCase() === 'X') {
return total + 10;
} else if (arrow.toUpperCase() === 'M') {
return total;
} else {
return total + parseInt(arrow);
}
}, 0);
};
// Get button color based on score
const getButtonColor = (score) => {
switch(score) {
case 'X':
return { bgcolor: '#FF9800', color: 'white' }; // Orange
case '10':
return { bgcolor: '#9C27B0', color: 'white' }; // Purple
case '9':
case '8':
return { bgcolor: '#2196F3', color: 'white' }; // Blue
case '7':
case '6':
case '5':
case '4':
case '3':
case '2':
case '1':
return { bgcolor: '#4CAF50', color: 'white' }; // Green
case 'M':
return { bgcolor: '#9E9E9E', color: 'white' }; // Gray
default:
return { bgcolor: 'default' };
}
};
// Handle saving the current end
const handleSaveEnd = () => {
if (currentEnd.length > 0) {
// Create the end object
const endObject = {
arrows: [...currentEnd],
total: calculateEndTotal(currentEnd),
timestamp: new Date().toISOString()
};
// Dispatch to context
dispatch({
type: ACTIONS.ADD_END,
payload: endObject
});
// Clear current end
setCurrentEnd([]);
}
};
// Handle ending the game
const handleEndGame = () => {
// Save final scores to history first
dispatch({
type: ACTIONS.START_GAME,
payload: {
gameType: selectedGameType,
isLeague: isLeague, // Pass the league/practice mode correctly
targetFace: selectedTargetFace
}
type: ACTIONS.SAVE_GAME,
});
onGameStart();
// Then end the current game
dispatch({
type: ACTIONS.END_GAME,
});
// Navigate to setup page
navigate('/');
};
// Early return if no game is active
if (!state.currentGame || !state.currentGame.gameType) {
return null; // Will be redirected by useEffect
}
// Get the number of arrows per end based on game type
const arrowsPerEnd = state.currentGame.gameType === '450' ? 6 : 5;
// Score button values
const scoreButtons = ['X', '10', '9', '8', '7', '6', '5', '4', '3', '2', '1', 'M'];
return (
<Grid container spacing={3} justifyContent="center" alignItems="center" style={{ minHeight: '80vh' }}>
<Grid item xs={12} sm={8} md={6}>
<Grid container spacing={3} justifyContent="center">
<Grid item xs={12} sm={10} md={8}>
<Card>
<CardHeader
title="Start New Game"
<CardHeader
title={`${state.currentGame.gameType} Round ${state.currentGame.isLeague ? '(League)' : '(Practice)'}`}
titleTypographyProps={{ align: 'center' }}
/>
<CardContent>
<Grid container spacing={3}>
<Grid item xs={12}>
<Typography variant="body1" align="center" gutterBottom>
Select your game type:
<Typography variant="h6" gutterBottom>
Target Face: {state.currentGame.targetFace || 'Standard'}
</Typography>
{/* Current game stats */}
<Box sx={{ mb: 3 }}>
<Paper elevation={2} sx={{ p: 2 }}>
<Typography variant="h6" gutterBottom>
Current Score: {state.currentGame.ends?.reduce((total, end) => total + end.total, 0) || 0}
</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>
{/* Select League or Practice Mode */}
<Grid item xs={12}>
<FormControl component="fieldset" fullWidth>
<Typography variant="body1" align="center" gutterBottom>
Select game mode:
</Typography>
<RadioGroup
row
name="gameMode"
value={isLeague ? "league" : "practice"} // Display correct mode
onChange={handleGameModeChange}
<Typography variant="body1">
Ends Completed: {state.currentGame.ends?.length || 0}
</Typography>
</Paper>
</Box>
{/* Score input section */}
<Box sx={{ mb: 3 }}>
<Typography variant="h6" gutterBottom>
Score Current End
</Typography>
{/* Score buttons */}
<Box sx={{ mb: 2 }}>
<Box sx={{ display: 'flex', flexWrap: 'wrap', mb: 1, gap: 0.5 }}>
{scoreButtons.map((score) => {
const colorStyle = getButtonColor(score);
return (
<Button
key={score}
variant="contained"
onClick={() => handleAddArrow(score)}
disabled={currentEnd.length >= arrowsPerEnd}
sx={{
minWidth: '45px',
bgcolor: colorStyle.bgcolor,
color: colorStyle.color,
'&:hover': {
bgcolor: colorStyle.bgcolor,
opacity: 0.9
}
}}
>
{score}
</Button>
);
})}
<IconButton
color="secondary"
onClick={handleRemoveArrow}
disabled={currentEnd.length === 0}
sx={{ ml: 1 }}
>
<FormControlLabel
value="practice"
control={<Radio />}
label="Practice"
/>
<FormControlLabel
value="league"
control={<Radio />}
label="League"
/>
</RadioGroup>
</FormControl>
</Grid>
{/* Target face selection */}
<Grid item xs={12}>
<FormControl fullWidth>
<Typography variant="body1" align="center" gutterBottom>
Select target face:
</Typography>
<Select
value={selectedTargetFace}
onChange={handleTargetFaceChange}
<Remove />
</IconButton>
</Box>
</Box>
{/* Current end display */}
<Box sx={{ display: 'flex', flexWrap: 'wrap', mb: 2 }}>
{currentEnd.map((arrow, index) => {
let bgColor;
if (arrow.toUpperCase() === 'X') bgColor = '#FF9800'; // Orange
else if (arrow.toUpperCase() === '10') bgColor = '#9C27B0'; // Purple
else if (['9', '8'].includes(arrow)) bgColor = '#2196F3'; // Blue
else if (['7', '6', '5', '4', '3', '2', '1'].includes(arrow)) bgColor = '#4CAF50'; // Green
else if (arrow.toUpperCase() === 'M') bgColor = '#9E9E9E'; // Gray
else bgColor = 'default';
return (
<Paper
key={index}
elevation={1}
sx={{
p: 1.5,
m: 0.5,
minWidth: '40px',
textAlign: 'center',
bgcolor: bgColor,
color: 'white'
}}
>
<Typography variant="h6">{arrow.toUpperCase()}</Typography>
</Paper>
);
})}
{Array(arrowsPerEnd - currentEnd.length).fill(0).map((_, index) => (
<Paper
key={`empty-${index}`}
elevation={1}
sx={{
p: 1.5,
m: 0.5,
minWidth: '40px',
textAlign: 'center',
bgcolor: '#f5f5f5'
}}
>
<MenuItem value="single">Single Spot</MenuItem>
<MenuItem value="five">Five Spot</MenuItem>
</Select>
</FormControl>
</Grid>
{/* Start Game Button */}
<Grid item xs={12}>
<Button
fullWidth
variant="contained"
color="primary"
size="large"
onClick={startGame}
disabled={!selectedGameType} // Disable button if no game type selected
<Typography variant="h6">-</Typography>
</Paper>
))}
</Box>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Typography variant="body1">
End Total: {calculateEndTotal(currentEnd)}
</Typography>
<Button
variant="contained"
color="primary"
onClick={handleSaveEnd}
disabled={currentEnd.length === 0 || currentEnd.length < arrowsPerEnd}
>
Start Game
Save End
</Button>
</Grid>
</Grid>
</Box>
</Box>
<Divider sx={{ my: 3 }} />
{/* Previous ends display */}
{(state.currentGame.ends?.length > 0) && (
<Box sx={{ mb: 3 }}>
<Typography variant="h6" gutterBottom>
Previous Ends
</Typography>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>End</TableCell>
<TableCell>Arrows</TableCell>
<TableCell>Total</TableCell>
<TableCell>Running Total</TableCell>
</TableRow>
</TableHead>
<TableBody>
{state.currentGame.ends.map((end, endIndex) => {
const runningTotal = state.currentGame.ends
.slice(0, endIndex + 1)
.reduce((total, e) => total + e.total, 0);
return (
<TableRow key={endIndex}>
<TableCell>{endIndex + 1}</TableCell>
<TableCell>
{end.arrows.join(', ')}
</TableCell>
<TableCell>{end.total}</TableCell>
<TableCell>{runningTotal}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
</Box>
)}
<Button
variant="contained"
color="secondary"
onClick={handleEndGame}
sx={{ mt: 3 }}
>
End Game
</Button>
</CardContent>
</Card>
</Grid>
@@ -158,5 +321,4 @@ const GameSetup = ({ onGameStart }) => {
);
};
export default GameSetup;
export default ScoreTracker;