Add marathon finish button and system
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { useParams, Link } from 'react-router-dom'
|
||||
import { marathonsApi, wheelApi, gamesApi, eventsApi, assignmentsApi } from '@/api'
|
||||
import type { Marathon, Assignment, SpinResult, Game, ActiveEvent, SwapCandidate, MySwapRequests, CommonEnemyLeaderboardEntry, EventAssignment, GameChoiceChallenges, ReturnedAssignment } from '@/types'
|
||||
import type { Marathon, Assignment, Game, ActiveEvent, SwapCandidate, MySwapRequests, CommonEnemyLeaderboardEntry, EventAssignment, GameChoiceChallenges, ReturnedAssignment } from '@/types'
|
||||
import { Button, Card, CardContent } from '@/components/ui'
|
||||
import { SpinWheel } from '@/components/SpinWheel'
|
||||
import { EventBanner } from '@/components/EventBanner'
|
||||
@@ -22,7 +22,6 @@ 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 [activeEvent, setActiveEvent] = useState<ActiveEvent | null>(null)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
@@ -219,7 +218,6 @@ export function PlayPage() {
|
||||
|
||||
try {
|
||||
const result = await wheelApi.spin(parseInt(id))
|
||||
setSpinResult(result)
|
||||
return result.game
|
||||
} catch (err: unknown) {
|
||||
const error = err as { response?: { data?: { detail?: string } } }
|
||||
@@ -256,7 +254,6 @@ export function PlayPage() {
|
||||
setProofFile(null)
|
||||
setProofUrl('')
|
||||
setComment('')
|
||||
setSpinResult(null)
|
||||
|
||||
await loadData()
|
||||
} catch (err: unknown) {
|
||||
@@ -270,7 +267,7 @@ export function PlayPage() {
|
||||
const handleDrop = async () => {
|
||||
if (!currentAssignment) return
|
||||
|
||||
const penalty = spinResult?.drop_penalty || 0
|
||||
const penalty = currentAssignment.drop_penalty
|
||||
const confirmed = await confirm({
|
||||
title: 'Пропустить задание?',
|
||||
message: `Вы потеряете ${penalty} очков.`,
|
||||
@@ -285,7 +282,6 @@ export function PlayPage() {
|
||||
const result = await wheelApi.drop(currentAssignment.id)
|
||||
toast.info(`Пропущено. Штраф: -${result.penalty} очков`)
|
||||
|
||||
setSpinResult(null)
|
||||
await loadData()
|
||||
} catch (err: unknown) {
|
||||
const error = err as { response?: { data?: { detail?: string } } }
|
||||
@@ -455,6 +451,42 @@ export function PlayPage() {
|
||||
return <div>Марафон не найден</div>
|
||||
}
|
||||
|
||||
// Check if marathon has ended by status or by date
|
||||
const marathonEndDate = marathon.end_date ? new Date(marathon.end_date) : null
|
||||
const isMarathonExpired = marathonEndDate && new Date() > marathonEndDate
|
||||
const isMarathonEnded = marathon.status === 'finished' || isMarathonExpired
|
||||
|
||||
if (isMarathonEnded) {
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<Link to={`/marathons/${id}`} className="inline-flex items-center gap-2 text-gray-400 hover:text-white mb-4 transition-colors">
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
К марафону
|
||||
</Link>
|
||||
|
||||
<Card>
|
||||
<CardContent className="text-center py-12">
|
||||
<div className="w-16 h-16 bg-gray-700 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<Trophy className="w-8 h-8 text-yellow-500" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-white mb-2">Марафон завершён</h2>
|
||||
<p className="text-gray-400 mb-6">
|
||||
{marathon.status === 'finished'
|
||||
? 'Этот марафон был завершён организатором.'
|
||||
: 'Этот марафон завершился по истечении срока.'}
|
||||
</p>
|
||||
<Link to={`/marathons/${id}/leaderboard`}>
|
||||
<Button>
|
||||
<Trophy className="w-4 h-4 mr-2" />
|
||||
Посмотреть итоговый рейтинг
|
||||
</Button>
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const participation = marathon.my_participation
|
||||
|
||||
return (
|
||||
@@ -1092,7 +1124,7 @@ export function PlayPage() {
|
||||
onClick={handleDrop}
|
||||
isLoading={isDropping}
|
||||
>
|
||||
Пропустить (-{spinResult?.drop_penalty || 0})
|
||||
Пропустить (-{currentAssignment.drop_penalty})
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user