Add game roll wheel
This commit is contained in:
@@ -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>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user