122 lines
2.8 KiB
JavaScript
122 lines
2.8 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'
|
|
};
|
|
|
|
const initialState = {
|
|
currentGame: {
|
|
gameType: '',
|
|
isLeague: false,
|
|
rounds: [],
|
|
totalScore: 0,
|
|
totalBullseyes: 0,
|
|
date: null
|
|
},
|
|
history: []
|
|
};
|
|
|
|
const scoreReducer = (state, action) => {
|
|
switch (action.type) {
|
|
case ACTIONS.START_NEW_ROUND:
|
|
return {
|
|
...state,
|
|
currentGame: {
|
|
gameType: action.payload.gameType,
|
|
isLeague: action.payload.isLeague,
|
|
rounds: [],
|
|
totalScore: 0,
|
|
totalBullseyes: 0,
|
|
dateStarted: new Date().toISOString(),
|
|
},
|
|
};
|
|
|
|
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;
|
|
};
|