feat: Initial project structure for WebTriviasMulti
- Backend: FastAPI + Python-SocketIO + SQLAlchemy - Models for categories, questions, game sessions, events - AI services for answer validation and question generation (Claude) - Room management with Redis - Game logic with stealing mechanics - Admin API for question management - Frontend: React + Vite + TypeScript + Tailwind - 5 visual themes (DRRR, Retro, Minimal, RGB, Anime 90s) - Real-time game with Socket.IO - Achievement system - Replay functionality - Sound effects per theme - Docker Compose for deployment - Design documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
104
frontend/src/stores/gameStore.ts
Normal file
104
frontend/src/stores/gameStore.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { create } from 'zustand'
|
||||
import type { GameRoom, Player, Question, ChatMessage, Achievement } from '../types'
|
||||
|
||||
interface GameState {
|
||||
// Room state
|
||||
room: GameRoom | null
|
||||
setRoom: (room: GameRoom | null) => void
|
||||
|
||||
// Player info
|
||||
playerName: string
|
||||
setPlayerName: (name: string) => void
|
||||
|
||||
// Current question
|
||||
currentQuestion: Question | null
|
||||
setCurrentQuestion: (question: Question | null) => void
|
||||
|
||||
// Timer
|
||||
timerEnd: Date | null
|
||||
setTimerEnd: (end: Date | null) => void
|
||||
|
||||
// Chat messages
|
||||
messages: ChatMessage[]
|
||||
addMessage: (message: ChatMessage) => void
|
||||
clearMessages: () => void
|
||||
|
||||
// Achievements
|
||||
achievements: Achievement[]
|
||||
setAchievements: (achievements: Achievement[]) => void
|
||||
unlockAchievement: (id: number) => void
|
||||
|
||||
// Game stats (for achievements tracking)
|
||||
stats: {
|
||||
correctStreak: number
|
||||
stealsAttempted: number
|
||||
stealsSuccessful: number
|
||||
categoryCorrect: Record<number, number>
|
||||
fastAnswers: number
|
||||
maxDeficit: number
|
||||
}
|
||||
updateStats: (updates: Partial<GameState['stats']>) => void
|
||||
resetStats: () => void
|
||||
|
||||
// UI state
|
||||
showStealPrompt: boolean
|
||||
setShowStealPrompt: (show: boolean) => void
|
||||
|
||||
// Reset
|
||||
resetGame: () => void
|
||||
}
|
||||
|
||||
const initialStats = {
|
||||
correctStreak: 0,
|
||||
stealsAttempted: 0,
|
||||
stealsSuccessful: 0,
|
||||
categoryCorrect: {},
|
||||
fastAnswers: 0,
|
||||
maxDeficit: 0,
|
||||
}
|
||||
|
||||
export const useGameStore = create<GameState>((set) => ({
|
||||
room: null,
|
||||
setRoom: (room) => set({ room }),
|
||||
|
||||
playerName: '',
|
||||
setPlayerName: (playerName) => set({ playerName }),
|
||||
|
||||
currentQuestion: null,
|
||||
setCurrentQuestion: (currentQuestion) => set({ currentQuestion }),
|
||||
|
||||
timerEnd: null,
|
||||
setTimerEnd: (timerEnd) => set({ timerEnd }),
|
||||
|
||||
messages: [],
|
||||
addMessage: (message) =>
|
||||
set((state) => ({ messages: [...state.messages, message].slice(-100) })),
|
||||
clearMessages: () => set({ messages: [] }),
|
||||
|
||||
achievements: [],
|
||||
setAchievements: (achievements) => set({ achievements }),
|
||||
unlockAchievement: (id) =>
|
||||
set((state) => ({
|
||||
achievements: state.achievements.map((a) =>
|
||||
a.id === id ? { ...a, unlocked: true, unlockedAt: new Date().toISOString() } : a
|
||||
),
|
||||
})),
|
||||
|
||||
stats: initialStats,
|
||||
updateStats: (updates) =>
|
||||
set((state) => ({ stats: { ...state.stats, ...updates } })),
|
||||
resetStats: () => set({ stats: initialStats }),
|
||||
|
||||
showStealPrompt: false,
|
||||
setShowStealPrompt: (showStealPrompt) => set({ showStealPrompt }),
|
||||
|
||||
resetGame: () =>
|
||||
set({
|
||||
room: null,
|
||||
currentQuestion: null,
|
||||
timerEnd: null,
|
||||
messages: [],
|
||||
stats: initialStats,
|
||||
showStealPrompt: false,
|
||||
}),
|
||||
}))
|
||||
Reference in New Issue
Block a user