updated functionality

This commit is contained in:
Administrator
2025-02-13 20:54:22 -05:00
parent 9027d9c52b
commit b8c911f28e

View File

@@ -1,6 +1,7 @@
// src/context/ScoreContext.js // src/context/ScoreContext.js
import React, { createContext, useContext, useReducer, useEffect } from 'react'; import React, { createContext, useContext, useReducer, useEffect } from 'react';
// Define action types
export const ACTIONS = { export const ACTIONS = {
ADD_ARROW: 'ADD_ARROW', ADD_ARROW: 'ADD_ARROW',
START_NEW_ROUND: 'START_NEW_ROUND', START_NEW_ROUND: 'START_NEW_ROUND',
@@ -11,116 +12,7 @@ export const ACTIONS = {
UPDATE_HANDICAP: 'UPDATE_HANDICAP' UPDATE_HANDICAP: 'UPDATE_HANDICAP'
}; };
// Reducer function // Initial state structure
const scoreReducer = (state, action) => {
let newState;
switch (action.type) {
case ACTIONS.ADD_ARROW:
const { roundIndex, score, isBullseye } = action.payload;
const updatedRounds = [...state.currentGame.rounds];
if (!updatedRounds[roundIndex]) {
updatedRounds[roundIndex] = { arrows: [], total: 0, bullseyes: 0 };
}
updatedRounds[roundIndex] = {
...updatedRounds[roundIndex],
arrows: [...updatedRounds[roundIndex].arrows, score],
total: updatedRounds[roundIndex].total + score,
bullseyes: updatedRounds[roundIndex].bullseyes + (isBullseye ? 1 : 0),
};
const totalScore = updatedRounds.reduce((sum, round) => sum + round.total, 0);
const totalBullseyes = updatedRounds.reduce((sum, round) => sum + round.bullseyes, 0);
newState = {
...state,
currentGame: {
...state.currentGame,
rounds: updatedRounds,
totalScore,
totalBullseyes,
},
};
break;
case ACTIONS.START_NEW_ROUND:
// If there's a current game, save it to history
const gamesHistory = state.currentGame.gameType ?
[...state.games, state.currentGame] :
state.games;
newState = {
games: gamesHistory,
currentGame: {
gameType: action.payload.gameType,
rounds: [],
totalScore: 0,
totalBullseyes: 0,
dateStarted: new Date().toISOString(),
},
};
break;
case ACTIONS.RESET_GAME:
newState = initialState;
break;
case ACTIONS.LOAD_SAVED_GAME:
newState = action.payload;
break;
default:
return state;
}
// Save to localStorage after every state change
localStorage.setItem('archeryScores', JSON.stringify(newState));
return newState;
};
// Create context
const ScoreContext = createContext();
// Context provider component
export const ScoreProvider = ({ children }) => {
// Load state from localStorage on initial render
const [state, dispatch] = useReducer(scoreReducer, initialState, () => {
try {
const localData = localStorage.getItem('archeryScores');
if (localData) {
const parsedData = JSON.parse(localData);
// Verify the data structure
if (parsedData.currentGame && parsedData.games) {
return parsedData;
}
}
} catch (error) {
console.error('Error loading saved game:', error);
}
return initialState;
});
return (
<ScoreContext.Provider value={{ state, dispatch }}>
{children}
</ScoreContext.Provider>
);
};
// Custom hook for using the score context
export const useScore = () => {
const context = useContext(ScoreContext);
if (!context) {
throw new Error('useScore must be used within a ScoreProvider');
}
return context;
};
// src/context/ScoreContext.js
// ... (keeping existing imports and initial setup)
const initialState = { const initialState = {
currentGame: { currentGame: {
id: null, id: null,
@@ -146,24 +38,71 @@ const initialState = {
}, },
}; };
// Handicap calculation function (basic version - can be adjusted based on your league's rules) // Handicap calculation function
const calculateHandicap = (scores) => { const calculateHandicap = (scores) => {
if (scores.length < 3) return null; if (scores.length < 3) return null;
// Take the average of the last 3 scores
const lastThree = scores.slice(-3); const lastThree = scores.slice(-3);
const average = lastThree.reduce((sum, game) => sum + game.totalScore, 0) / 3; const average = lastThree.reduce((sum, game) => sum + game.totalScore, 0) / 3;
// Example handicap calculation (adjust formula as needed)
const maxPossibleScore = scores[0].gameType === '450' ? 450 : 300; const maxPossibleScore = scores[0].gameType === '450' ? 450 : 300;
const handicap = Math.round((maxPossibleScore - average) * 0.8); const handicap = Math.round((maxPossibleScore - average) * 0.8);
return Math.max(0, Math.min(100, handicap)); // Cap between 0 and 100 return Math.max(0, Math.min(100, handicap));
}; };
// Reducer function
const scoreReducer = (state, action) => { const scoreReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case ACTIONS.START_NEW_GAME: case ACTIONS.ADD_ARROW: {
const { roundIndex, score, isBullseye } = action.payload;
const updatedRounds = [...state.currentGame.rounds];
if (!updatedRounds[roundIndex]) {
updatedRounds[roundIndex] = { arrows: [], total: 0, bullseyes: 0 };
}
updatedRounds[roundIndex] = {
...updatedRounds[roundIndex],
arrows: [...updatedRounds[roundIndex].arrows, score],
total: updatedRounds[roundIndex].total + score,
bullseyes: updatedRounds[roundIndex].bullseyes + (isBullseye ? 1 : 0),
};
const totalScore = updatedRounds.reduce((sum, round) => sum + round.total, 0);
const totalBullseyes = updatedRounds.reduce((sum, round) => sum + round.bullseyes, 0);
return {
...state,
currentGame: {
...state.currentGame,
rounds: updatedRounds,
totalScore,
totalBullseyes,
},
};
}
case ACTIONS.START_NEW_ROUND: {
const gamesHistory = state.currentGame.gameType ?
[...state.games, state.currentGame] :
state.games;
return {
...state,
games: gamesHistory,
currentGame: {
...state.currentGame,
gameType: action.payload.gameType,
rounds: [],
totalScore: 0,
totalBullseyes: 0,
dateStarted: new Date().toISOString(),
},
};
}
case ACTIONS.START_NEW_GAME: {
const { gameType, category } = action.payload; const { gameType, category } = action.payload;
return { return {
...state, ...state,
@@ -175,19 +114,19 @@ const scoreReducer = (state, action) => {
dateStarted: new Date().toISOString(), dateStarted: new Date().toISOString(),
}, },
}; };
}
case ACTIONS.SAVE_GAME: case ACTIONS.SAVE_GAME: {
const completedGame = { const completedGame = {
...state.currentGame, ...state.currentGame,
dateCompleted: new Date().toISOString(), dateCompleted: new Date().toISOString(),
}; };
// Calculate handicap for league games
if (completedGame.category === 'league') { if (completedGame.category === 'league') {
const relevantGames = [...state.games.league, completedGame] const relevantGames = [...state.games.league, completedGame]
.filter(game => game.gameType === completedGame.gameType) .filter(game => game.gameType === completedGame.gameType)
.sort((a, b) => new Date(b.dateCompleted) - new Date(a.dateCompleted)); .sort((a, b) => new Date(b.dateCompleted) - new Date(a.dateCompleted));
completedGame.handicap = calculateHandicap(relevantGames); completedGame.handicap = calculateHandicap(relevantGames);
} }
@@ -199,7 +138,6 @@ const scoreReducer = (state, action) => {
], ],
}; };
// Update statistics
const updateAverages = (games, type, category) => { const updateAverages = (games, type, category) => {
const relevantGames = games.filter(game => game.gameType === type); const relevantGames = games.filter(game => game.gameType === type);
return relevantGames.length > 0 return relevantGames.length > 0
@@ -227,12 +165,58 @@ const scoreReducer = (state, action) => {
games: newGames, games: newGames,
statistics: newStatistics, statistics: newStatistics,
}; };
}
// ... (existing cases) case ACTIONS.RESET_GAME:
return initialState;
case ACTIONS.LOAD_SAVED_GAME:
return action.payload;
default: default:
return state; return state;
} }
}; };
// ... (rest of the context implementation) // Create context
const ScoreContext = createContext();
// Context provider component
export const ScoreProvider = ({ children }) => {
const [state, dispatch] = useReducer(scoreReducer, initialState, () => {
try {
const localData = localStorage.getItem('archeryScores');
if (localData) {
const parsedData = JSON.parse(localData);
if (parsedData.currentGame && parsedData.games) {
return parsedData;
}
}
} catch (error) {
console.error('Error loading saved game:', error);
}
return initialState;
});
// Save to localStorage after every state change
useEffect(() => {
localStorage.setItem('archeryScores', JSON.stringify(state));
}, [state]);
return (
<ScoreContext.Provider value={{ state, dispatch }}>
{children}
</ScoreContext.Provider>
);
};
// Custom hook for using the score context
export const useScore = () => {
const context = useContext(ScoreContext);
if (!context) {
throw new Error('useScore must be used within a ScoreProvider');
}
return context;
};
export default ScoreContext;