Add game roll wheel

This commit is contained in:
2025-12-14 21:41:49 +07:00
parent 5db2f9c48d
commit 1a882fb2e0
2 changed files with 237 additions and 22 deletions

View File

@@ -1,8 +1,9 @@
import { useState, useEffect, useRef } from 'react'
import { useParams } from 'react-router-dom'
import { marathonsApi, wheelApi } from '@/api'
import type { Marathon, Assignment, SpinResult } from '@/types'
import { marathonsApi, wheelApi, gamesApi } from '@/api'
import type { Marathon, Assignment, SpinResult, Game } from '@/types'
import { Button, Card, CardContent } from '@/components/ui'
import { SpinWheel } from '@/components/SpinWheel'
import { Loader2, Upload, X } from 'lucide-react'
export function PlayPage() {
@@ -11,11 +12,9 @@ export function PlayPage() {
const [marathon, setMarathon] = useState<Marathon | null>(null)
const [currentAssignment, setCurrentAssignment] = useState<Assignment | null>(null)
const [spinResult, setSpinResult] = useState<SpinResult | null>(null)
const [games, setGames] = useState<Game[]>([])
const [isLoading, setIsLoading] = useState(true)
// Spin state
const [isSpinning, setIsSpinning] = useState(false)
// Complete state
const [proofFile, setProofFile] = useState<File | null>(null)
const [proofUrl, setProofUrl] = useState('')
@@ -34,12 +33,14 @@ export function PlayPage() {
const loadData = async () => {
if (!id) return
try {
const [marathonData, assignment] = await Promise.all([
const [marathonData, assignment, gamesData] = await Promise.all([
marathonsApi.get(parseInt(id)),
wheelApi.getCurrentAssignment(parseInt(id)),
gamesApi.list(parseInt(id), 'approved'),
])
setMarathon(marathonData)
setCurrentAssignment(assignment)
setGames(gamesData)
} catch (error) {
console.error('Failed to load data:', error)
} finally {
@@ -47,24 +48,27 @@ export function PlayPage() {
}
}
const handleSpin = async () => {
if (!id) return
const handleSpin = async (): Promise<Game | null> => {
if (!id) return null
setIsSpinning(true)
setSpinResult(null)
try {
const result = await wheelApi.spin(parseInt(id))
setSpinResult(result)
// Reload to get assignment
await loadData()
return result.game
} catch (err: unknown) {
const error = err as { response?: { data?: { detail?: string } } }
alert(error.response?.data?.detail || 'Не удалось крутить')
} finally {
setIsSpinning(false)
return null
}
}
const handleSpinComplete = async () => {
// Small delay then reload data to show the assignment
setTimeout(async () => {
await loadData()
}, 500)
}
const handleComplete = async () => {
if (!currentAssignment) return
if (!proofFile && !proofUrl) {
@@ -162,17 +166,19 @@ export function PlayPage() {
</Card>
</div>
{/* No active assignment - show spin */}
{/* No active assignment - show spin wheel */}
{!currentAssignment && (
<Card className="text-center">
<CardContent className="py-12">
<h2 className="text-2xl font-bold text-white mb-4">Крутите колесо!</h2>
<p className="text-gray-400 mb-8">
<Card>
<CardContent className="py-8">
<h2 className="text-2xl font-bold text-white mb-2 text-center">Крутите колесо!</h2>
<p className="text-gray-400 mb-6 text-center">
Получите случайную игру и задание для выполнения
</p>
<Button size="lg" onClick={handleSpin} isLoading={isSpinning}>
{isSpinning ? 'Крутим...' : 'КРУТИТЬ'}
</Button>
<SpinWheel
games={games}
onSpin={handleSpin}
onSpinComplete={handleSpinComplete}
/>
</CardContent>
</Card>
)}