import { prisma } from "@/lib/prisma" export const dynamic = "force-dynamic"; import Navigation from "@/components/Navigation" import Link from "next/link" import { notFound } from "next/navigation" interface PageProps { params: { id: string } } export default async function PlayerProfilePage({ params }: PageProps) { // Next.js 16 requires awaiting params const { id } = await params const playerId = parseInt(id, 10) if (isNaN(playerId)) { notFound() } const player = await prisma.player.findUnique({ where: { id: playerId }, include: { eloRating: true, openSkillRating: true, glicko2Rating: true, }, }) if (!player) { notFound() } // Get partnership stats separately const partnershipStats = await prisma.partnershipStat.findMany({ where: { OR: [ { player1Id: playerId }, { player2Id: playerId }, ], }, include: { player1: true, player2: true, }, orderBy: { gamesPlayed: "desc" }, }) // Get tournaments participated in const tournaments = await prisma.event.findMany({ where: { participants: { some: { playerId: playerId, }, }, }, orderBy: { eventDate: "desc" }, take: 10, }) // Get recent matches (last 10 games played) const recentMatches = await prisma.match.findMany({ where: { OR: [ { team1P1Id: playerId }, { team1P2Id: playerId }, { team2P1Id: playerId }, { team2P2Id: playerId }, ], }, include: { team1P1: true, team1P2: true, team2P1: true, team2P2: true, event: true, }, orderBy: { playedAt: "desc" }, take: 10, }) // Use direct player stats for overall statistics (more accurate and consistent with rankings page) const totalGames = player.gamesPlayed const totalWins = player.wins const winRate = totalGames > 0 ? ((totalWins / totalGames) * 100).toFixed(1) : "0.0" // Get best partnership based on ELO contribution // Best partner is the one who contributed most to your rating (highest totalEloChange) // Must have played at least 2 games together to be considered const bestPartnership = partnershipStats.reduce((best, stat) => { if (stat.gamesPlayed < 2) return best // Need at least 2 games for partnership to be meaningful const currentEloChange = stat.totalEloChange const bestEloChange = best ? best.totalEloChange : -Infinity return currentEloChange > bestEloChange ? stat : best }, null as (typeof partnershipStats[0] | null)) return (
{/* Player Header */}
{player.name.charAt(0).toUpperCase()}

{player.name}

Member since {new Date(player.createdAt).toLocaleDateString()}

{/* Stats Grid */}

Current Elo

{player.currentElo}

OpenSkill Rating

{player.openSkillRating?.rating?.toFixed(1) || 'N/A'}

Glicko2 Rating

{player.glicko2Rating?.rating?.toFixed(1) || 'N/A'}

Best Partner

{bestPartnership ? (bestPartnership.player1Id === player.id ? bestPartnership.player2.name : bestPartnership.player1.name) : "N/A"}

{/* Tournaments Participated */}

Tournaments Participated

{tournaments.length === 0 ? (

No tournament data available yet.

) : (
{tournaments.map((tournament) => ( ))}
Tournament Date Format Status
{tournament.name} {tournament.eventDate ? new Date(tournament.eventDate).toLocaleDateString() : "N/A"} {tournament.format} {tournament.status}
)}
{/* Recent Games */}

Recent Games

{recentMatches.length === 0 ? (

No game data available yet.

) : (
{recentMatches.map((match) => { const isTeam1 = match.team1P1Id === playerId || match.team1P2Id === playerId; const teamWon = isTeam1 ? match.team1Score > match.team2Score : match.team2Score > match.team1Score; const teamScore = isTeam1 ? match.team1Score : match.team2Score; const opponentScore = isTeam1 ? match.team2Score : match.team1Score; const teammate = isTeam1 ? (match.team1P1Id === playerId ? match.team1P2 : match.team1P1) : (match.team2P1Id === playerId ? match.team2P2 : match.team2P1); const opponents = isTeam1 ? [match.team2P1, match.team2P2] : [match.team1P1, match.team1P2]; return ( ) })}
Date Tournament Team Opponents Score Result
{match.playedAt ? new Date(match.playedAt).toLocaleDateString() : "N/A"} {match.event?.name || "N/A"} {teammate.name} {opponents.map((opponent, index) => ( {opponent.name} {index < opponents.length - 1 ? ", " : ""} ))} {teamScore} - {opponentScore} {teamWon ? 'Win' : 'Loss'}
)}
{/* Partnership Performance */}

Partnership Performance

{partnershipStats.length === 0 ? (

No partnership data available yet.

) : (
{partnershipStats.map((stat) => { const partner = stat.player1Id === player.id ? stat.player2 : stat.player1 const winRate = stat.gamesPlayed > 0 ? ((stat.wins / stat.gamesPlayed) * 100).toFixed(1) : "0.0" return ( ) })}
Partner Games Win Rate ELO Change Last Played
{partner.name} {stat.gamesPlayed} {winRate}% = 0 ? 'text-green-600' : 'text-red-600' }`}> {stat.totalEloChange >= 0 ? '+' : ''}{stat.totalEloChange} {stat.lastPlayed ? new Date(stat.lastPlayed).toLocaleDateString() : "N/A"}
)}
) }