110 lines
3.4 KiB
TypeScript
110 lines
3.4 KiB
TypeScript
// src/app/api/team/[teamId]/route.ts
|
|
import { NextResponse, type NextRequest } from 'next/server'
|
|
import { prisma } from '@/app/lib/prisma'
|
|
import type { Player, InvitedPlayer } from '@/app/types/team'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
export const revalidate = 0
|
|
|
|
export async function GET(
|
|
_req: NextRequest,
|
|
{ params }: { params: { teamId: string } },
|
|
) {
|
|
try {
|
|
/* 1) Team + Leader + Invites (mit user) laden */
|
|
const team = await prisma.team.findUnique({
|
|
where: { id: params.teamId },
|
|
include: {
|
|
leader: true, // ⬅ damit wir ein Player-Objekt für leader bauen können
|
|
invites: {
|
|
include: { user: true }, // ⬅ notwendig für invitedPlayers
|
|
},
|
|
},
|
|
})
|
|
|
|
if (!team) {
|
|
return NextResponse.json({ error: 'Team nicht gefunden' }, { status: 404 })
|
|
}
|
|
|
|
/* 2) Aktive + Inaktive Spieler-Objekte bauen */
|
|
const allIds = Array.from(new Set([...(team.activePlayers ?? []), ...(team.inactivePlayers ?? [])]))
|
|
|
|
const users = allIds.length
|
|
? await prisma.user.findMany({
|
|
where: { steamId: { in: allIds } },
|
|
select: {
|
|
steamId: true,
|
|
name: true,
|
|
avatar: true,
|
|
location: true,
|
|
premierRank: true,
|
|
isAdmin: true,
|
|
},
|
|
})
|
|
: []
|
|
|
|
const toPlayer = (u: any): Player => ({
|
|
steamId: u.steamId,
|
|
name: u.name ?? 'Unbekannt',
|
|
avatar: u.avatar ?? '/assets/img/avatars/default.png',
|
|
location: u.location ?? undefined,
|
|
premierRank: u.premierRank ?? undefined,
|
|
isAdmin: u.isAdmin ?? undefined,
|
|
})
|
|
|
|
const byId: Record<string, Player> = Object.fromEntries(users.map(u => [u.steamId, toPlayer(u)]))
|
|
|
|
const safeSort = (a?: string, b?: string) => (a ?? '').localeCompare(b ?? '')
|
|
|
|
const activePlayers: Player[] = (team.activePlayers ?? [])
|
|
.map(id => byId[id])
|
|
.filter(Boolean)
|
|
.sort((a, b) => safeSort(a.name, b.name))
|
|
|
|
const inactivePlayers: Player[] = (team.inactivePlayers ?? [])
|
|
.map(id => byId[id])
|
|
.filter(Boolean)
|
|
.sort((a, b) => safeSort(a.name, b.name))
|
|
|
|
/* 3) Eingeladene Spieler inkl. invitationId */
|
|
const invitedPlayers: InvitedPlayer[] = (team.invites ?? [])
|
|
.map(inv => {
|
|
const u = inv.user
|
|
return {
|
|
invitationId: inv.id, // ⬅ passt zu deinem InvitedPlayer-Typ
|
|
steamId: u.steamId,
|
|
name: u.name ?? 'Unbekannt',
|
|
avatar: u.avatar ?? '/assets/img/avatars/default.png',
|
|
location: u.location ?? undefined,
|
|
premierRank: u.premierRank ?? undefined,
|
|
isAdmin: u.isAdmin ?? undefined,
|
|
}
|
|
})
|
|
.sort((a, b) => safeSort(a.name, b.name))
|
|
|
|
/* 4) Leader als Player-Objekt (nicht leaderId-String) */
|
|
const leader: Player | undefined = team.leader
|
|
? toPlayer(team.leader)
|
|
: undefined
|
|
|
|
/* 5) Antwort */
|
|
const result = {
|
|
id: team.id,
|
|
name: team.name,
|
|
logo: team.logo,
|
|
leader, // ⬅ jetzt Player statt String
|
|
createdAt: team.createdAt,
|
|
activePlayers,
|
|
inactivePlayers,
|
|
invitedPlayers,
|
|
}
|
|
|
|
return NextResponse.json(result, {
|
|
headers: { 'Cache-Control': 'no-store, no-cache, max-age=0, must-revalidate' },
|
|
})
|
|
} catch (error) {
|
|
console.error('GET /api/team/[teamId] failed:', error)
|
|
return NextResponse.json({ error: 'Interner Serverfehler' }, { status: 500 })
|
|
}
|
|
}
|