feat: Add statistics tracking and fix clipboard API
- Add personal statistics with badges for each attempt count - Track solved puzzles per attempt (1-6) and failed attempts - Display statistics after game completion - Fix clipboard API issue with fallback method - Add footer with attribution
This commit is contained in:
@@ -10,12 +10,25 @@ export interface GameState {
|
||||
lastPlayed: number; // Timestamp
|
||||
}
|
||||
|
||||
export interface Statistics {
|
||||
solvedIn1: number;
|
||||
solvedIn2: number;
|
||||
solvedIn3: number;
|
||||
solvedIn4: number;
|
||||
solvedIn5: number;
|
||||
solvedIn6: number;
|
||||
failed: number;
|
||||
}
|
||||
|
||||
const STORAGE_KEY = 'hoerdle_game_state';
|
||||
const STATS_KEY = 'hoerdle_statistics';
|
||||
|
||||
export function useGameState() {
|
||||
const [gameState, setGameState] = useState<GameState | null>(null);
|
||||
const [statistics, setStatistics] = useState<Statistics | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Load game state
|
||||
const stored = localStorage.getItem(STORAGE_KEY);
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
|
||||
@@ -23,20 +36,48 @@ export function useGameState() {
|
||||
const parsed: GameState = JSON.parse(stored);
|
||||
if (parsed.date === today) {
|
||||
setGameState(parsed);
|
||||
return;
|
||||
} else {
|
||||
// New day
|
||||
const newState: GameState = {
|
||||
date: today,
|
||||
guesses: [],
|
||||
isSolved: false,
|
||||
isFailed: false,
|
||||
lastPlayed: Date.now(),
|
||||
};
|
||||
setGameState(newState);
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(newState));
|
||||
}
|
||||
} else {
|
||||
// No state
|
||||
const newState: GameState = {
|
||||
date: today,
|
||||
guesses: [],
|
||||
isSolved: false,
|
||||
isFailed: false,
|
||||
lastPlayed: Date.now(),
|
||||
};
|
||||
setGameState(newState);
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(newState));
|
||||
}
|
||||
|
||||
// New day or no state
|
||||
const newState: GameState = {
|
||||
date: today,
|
||||
guesses: [],
|
||||
isSolved: false,
|
||||
isFailed: false,
|
||||
lastPlayed: Date.now(),
|
||||
};
|
||||
setGameState(newState);
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(newState));
|
||||
// Load statistics
|
||||
const storedStats = localStorage.getItem(STATS_KEY);
|
||||
if (storedStats) {
|
||||
setStatistics(JSON.parse(storedStats));
|
||||
} else {
|
||||
const newStats: Statistics = {
|
||||
solvedIn1: 0,
|
||||
solvedIn2: 0,
|
||||
solvedIn3: 0,
|
||||
solvedIn4: 0,
|
||||
solvedIn5: 0,
|
||||
solvedIn6: 0,
|
||||
failed: 0,
|
||||
};
|
||||
setStatistics(newStats);
|
||||
localStorage.setItem(STATS_KEY, JSON.stringify(newStats));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const saveState = (newState: GameState) => {
|
||||
@@ -44,6 +85,28 @@ export function useGameState() {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(newState));
|
||||
};
|
||||
|
||||
const updateStatistics = (attempts: number, solved: boolean) => {
|
||||
if (!statistics) return;
|
||||
|
||||
const newStats = { ...statistics };
|
||||
|
||||
if (solved) {
|
||||
switch (attempts) {
|
||||
case 1: newStats.solvedIn1++; break;
|
||||
case 2: newStats.solvedIn2++; break;
|
||||
case 3: newStats.solvedIn3++; break;
|
||||
case 4: newStats.solvedIn4++; break;
|
||||
case 5: newStats.solvedIn5++; break;
|
||||
case 6: newStats.solvedIn6++; break;
|
||||
}
|
||||
} else {
|
||||
newStats.failed++;
|
||||
}
|
||||
|
||||
setStatistics(newStats);
|
||||
localStorage.setItem(STATS_KEY, JSON.stringify(newStats));
|
||||
};
|
||||
|
||||
const addGuess = (guess: string, correct: boolean) => {
|
||||
if (!gameState) return;
|
||||
|
||||
@@ -60,7 +123,12 @@ export function useGameState() {
|
||||
};
|
||||
|
||||
saveState(newState);
|
||||
|
||||
// Update statistics when game ends
|
||||
if (isSolved || isFailed) {
|
||||
updateStatistics(newGuesses.length, isSolved);
|
||||
}
|
||||
};
|
||||
|
||||
return { gameState, addGuess };
|
||||
return { gameState, statistics, addGuess };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user