Files
ASC/asc/src/context/ScoreContext.js
corey@blaishome.online e2931a5cdb Started work on 5spot
2025-02-26 21:48:49 -05:00

160 lines
4.3 KiB
JavaScript

import React, { createContext, useContext, useReducer, useEffect } from 'react';
export const ACTIONS = {
START_GAME: 'start_game',
ADD_ROUND: 'add_round',
RESET_GAME: 'reset_game',
SAVE_GAME: 'save_game',
LOAD_HISTORY: 'load_history',
SET_TARGET_FACE: 'set_target_face'
};
// Define the available score values for each game type and target face
export const TARGET_FACES = {
'300': {
'standard': [0, 1, 2, 3, 4, 5, 'x'], // Standard scoring for 300 game
'5-spot': [0, 4, 5, 'x'] // 5-spot target face for 300 game
},
'450': {
'standard': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'x'], // Standard scoring for 450 game
'3-spot': [0, 6, 7, 8, 9, 10, 'x'] // 3-spot target face for 450 game
}
};
const initialState = {
currentGame: {
gameType: '',
isLeague: false,
targetFace: 'standard', // Default to standard target face
rounds: [],
totalScore: 0,
totalBullseyes: 0,
date: null,
availableScores: [] // Will be populated based on gameType and targetFace
},
history: []
};
// Helper function to get available scores based on game type and target face
const getAvailableScores = (gameType, targetFace) => {
if (!gameType || !targetFace) return [];
return TARGET_FACES[gameType]?.[targetFace] || [];
};
const scoreReducer = (state, action) => {
switch (action.type) {
case ACTIONS.START_GAME: // Changed from START_NEW_ROUND to match the exported ACTIONS
const gameType = action.payload.gameType;
const targetFace = action.payload.targetFace || 'standard';
return {
...state,
currentGame: {
gameType,
isLeague: action.payload.isLeague,
targetFace,
rounds: [],
totalScore: 0,
totalBullseyes: 0,
dateStarted: new Date().toISOString(),
availableScores: getAvailableScores(gameType, targetFace)
},
};
case ACTIONS.SET_TARGET_FACE:
const newTargetFace = action.payload.targetFace;
return {
...state,
currentGame: {
...state.currentGame,
targetFace: newTargetFace,
availableScores: getAvailableScores(state.currentGame.gameType, newTargetFace)
}
};
case ACTIONS.ADD_ROUND:
const updatedRounds = [...state.currentGame.rounds];
updatedRounds[action.payload.roundIndex] = {
arrows: action.payload.arrows,
total: action.payload.total,
bullseyes: action.payload.arrows.filter(arrow => arrow.isBullseye).length
};
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.SAVE_GAME:
if (!state.currentGame.isLeague) return state; // Only save league games
const updatedHistory = [
...state.history,
{ ...state.currentGame }
];
// Save to localStorage
localStorage.setItem('archeryHistory', JSON.stringify(updatedHistory));
return {
...state,
history: updatedHistory
};
case ACTIONS.LOAD_HISTORY:
return {
...state,
history: action.payload
};
case ACTIONS.RESET_GAME:
return {
...state,
currentGame: initialState.currentGame
};
default:
return state;
}
};
const ScoreContext = createContext();
export const ScoreProvider = ({ children }) => {
const [state, dispatch] = useReducer(scoreReducer, initialState);
// Load history from localStorage on initial mount
useEffect(() => {
const savedHistory = localStorage.getItem('archeryHistory');
if (savedHistory) {
dispatch({
type: ACTIONS.LOAD_HISTORY,
payload: JSON.parse(savedHistory)
});
}
}, []);
return (
<ScoreContext.Provider value={{ state, dispatch }}>
{children}
</ScoreContext.Provider>
);
};
export const useScore = () => {
const context = useContext(ScoreContext);
if (!context) {
throw new Error('useScore must be used within a ScoreProvider');
}
return context;
};