Add marathon finish button and system

This commit is contained in:
2025-12-16 02:22:12 +07:00
parent d96f8de568
commit f57a2ba9ea
5 changed files with 89 additions and 8 deletions

View File

@@ -9,7 +9,7 @@ import { useConfirm } from '@/store/confirm'
import { EventBanner } from '@/components/EventBanner'
import { EventControl } from '@/components/EventControl'
import { ActivityFeed, type ActivityFeedRef } from '@/components/ActivityFeed'
import { Users, Calendar, Trophy, Play, Settings, Copy, Check, Loader2, Trash2, Globe, Lock, CalendarCheck, UserPlus, Gamepad2, ArrowLeft, Zap } from 'lucide-react'
import { Users, Calendar, Trophy, Play, Settings, Copy, Check, Loader2, Trash2, Globe, Lock, CalendarCheck, UserPlus, Gamepad2, ArrowLeft, Zap, Flag } from 'lucide-react'
import { format } from 'date-fns'
export function MarathonPage() {
@@ -25,6 +25,7 @@ export function MarathonPage() {
const [copied, setCopied] = useState(false)
const [isDeleting, setIsDeleting] = useState(false)
const [isJoining, setIsJoining] = useState(false)
const [isFinishing, setIsFinishing] = useState(false)
const [showEventControl, setShowEventControl] = useState(false)
const activityFeedRef = useRef<ActivityFeedRef>(null)
@@ -125,6 +126,31 @@ export function MarathonPage() {
}
}
const handleFinish = async () => {
if (!marathon) return
const confirmed = await confirm({
title: 'Завершить марафон?',
message: 'Марафон будет завершён досрочно. Участники больше не смогут выполнять задания.',
confirmText: 'Завершить',
cancelText: 'Отмена',
variant: 'warning',
})
if (!confirmed) return
setIsFinishing(true)
try {
const updated = await marathonsApi.finish(marathon.id)
setMarathon(updated)
toast.success('Марафон завершён')
} catch (err: unknown) {
const error = err as { response?: { data?: { detail?: string } } }
toast.error(error.response?.data?.detail || 'Не удалось завершить марафон')
} finally {
setIsFinishing(false)
}
}
if (isLoading || !marathon) {
return (
<div className="flex justify-center py-12">
@@ -216,6 +242,18 @@ export function MarathonPage() {
</Button>
</Link>
{marathon.status === 'active' && isOrganizer && (
<Button
variant="secondary"
onClick={handleFinish}
isLoading={isFinishing}
className="text-yellow-400 hover:text-yellow-300 hover:bg-yellow-900/20"
>
<Flag className="w-4 h-4 mr-2" />
Завершить
</Button>
)}
{canDelete && (
<Button
variant="ghost"