2025-08-15 13:34:23 +02:00

111 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextResponse } from 'next/server'
import { prisma } from '@/app/lib/prisma'
export async function GET(req: Request) {
try {
const { searchParams } = new URL(req.url)
const matchType = searchParams.get('type') // z. B. "community"
const matches = await prisma.match.findMany({
where : matchType ? { matchType } : undefined,
orderBy: { demoDate: 'desc' },
include: {
teamA : true,
teamB : true,
players: { include: { user: true, stats: true, team: true } },
mapVote: { include: { steps: true } },
},
})
const formatted = matches.map(m => {
let status: 'not_started' | 'in_progress' | 'completed' | null = null
let opensAtISO: string | null = null
let isOpen = false // <-- immer boolean
let currentIndex: number | null = null
let currentAction: 'BAN'|'PICK'|'DECIDER' | null = null
let decidedCount: number | null = null
let totalSteps: number | null = null
let opensInMinutes: number | null = null // <-- optional
if (m.mapVote) {
const stepsSorted = [...m.mapVote.steps].sort((a, b) => a.order - b.order)
const anyChosen = stepsSorted.some(s => !!s.chosenAt)
status = m.mapVote.locked ? 'completed' : (anyChosen ? 'in_progress' : 'not_started')
const computedOpensAt =
m.mapVote.opensAt ??
(() => {
const base = m.matchDate ?? m.demoDate ?? new Date()
return new Date(base.getTime() - 60 * 60 * 1000) // 1h vorher
})()
opensAtISO = computedOpensAt?.toISOString() ?? null
if (opensAtISO) {
const now = Date.now()
const oa = new Date(opensAtISO).getTime()
isOpen = now >= oa
opensInMinutes = Math.max(0, Math.ceil((oa - now) / 60000))
}
currentIndex = m.mapVote.currentIdx
const cur = stepsSorted.find(s => s.order === m.mapVote?.currentIdx)
currentAction = (cur?.action as 'BAN'|'PICK'|'DECIDER') ?? null
decidedCount = stepsSorted.filter(s => !!s.chosenAt).length
totalSteps = stepsSorted.length
}
// Fallback für Anzeige-Datum im Frontend
const displayDate = m.demoDate ?? m.matchDate
return {
id : m.id,
map : m.map,
demoDate : m.demoDate, // unverändert
matchDate : m.matchDate, // falls dus im UI brauchst
displayDate, // <-- neu (für sicheres Rendern)
matchType : m.matchType,
scoreA : m.scoreA,
scoreB : m.scoreB,
winnerTeam: m.winnerTeam ?? null,
mapVote: m.mapVote ? {
status,
opensAt: opensAtISO,
isOpen,
opensInMinutes, // <-- optional
currentIndex,
currentAction,
decidedCount,
totalSteps,
} : null,
teamA: {
id : m.teamA?.id ?? null,
name : m.teamA?.name ?? 'CT',
logo : m.teamA?.logo ?? null,
score: m.scoreA,
},
teamB: {
id : m.teamB?.id ?? null,
name : m.teamB?.name ?? 'T',
logo : m.teamB?.logo ?? null,
score: m.scoreB,
},
players: m.players.map(p => ({
steamId : p.steamId,
name : p.user?.name,
avatar : p.user?.avatar,
stats : p.stats,
teamId : p.teamId,
teamName: p.team?.name ?? null,
})),
}
})
return NextResponse.json(formatted)
} catch (err) {
console.error('GET /matches failed:', err)
return NextResponse.json({ error: 'Failed to load matches' }, { status: 500 })
}
}