refactor(ui): update components to use new player field names

This commit is contained in:
2026-04-03 21:03:57 -07:00
parent c00f26919b
commit 52da77d57b
9 changed files with 193 additions and 212 deletions
+15 -50
View File
@@ -40,28 +40,14 @@ export default async function TournamentDetailPage({ params }: PageProps) {
player: true,
},
},
teams: {
include: {
player1: true,
player2: true,
},
},
rounds: {
include: {
bracketMatchups: {
include: {
team1: {
include: {
player1: true,
player2: true,
},
},
team2: {
include: {
player1: true,
player2: true,
},
},
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
match: true,
},
},
@@ -86,28 +72,14 @@ export default async function TournamentDetailPage({ params }: PageProps) {
player: true,
},
},
teams: {
include: {
player1: true,
player2: true,
},
},
rounds: {
include: {
bracketMatchups: {
include: {
team1: {
include: {
player1: true,
player2: true,
},
},
team2: {
include: {
player1: true,
player2: true,
},
},
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
match: true,
},
},
@@ -120,10 +92,10 @@ export default async function TournamentDetailPage({ params }: PageProps) {
const matches = await prisma.match.findMany({
where: { eventId: tournamentId },
include: {
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
},
orderBy: { playedAt: "desc" },
})
@@ -204,12 +176,6 @@ export default async function TournamentDetailPage({ params }: PageProps) {
{tournament.participants.length}
</p>
</div>
<div className="bg-gray-50 rounded-lg p-4 text-center">
<p className="text-sm text-gray-500">Teams</p>
<p className="text-2xl font-bold text-gray-900">
{tournament.teams.length}
</p>
</div>
<div className="bg-gray-50 rounded-lg p-4 text-center">
<p className="text-sm text-gray-500">Rounds</p>
<p className="text-2xl font-bold text-gray-900">
@@ -217,7 +183,7 @@ export default async function TournamentDetailPage({ params }: PageProps) {
</p>
</div>
<div className="bg-gray-50 rounded-lg p-4 text-center">
<p className="text-sm text-gray-500">Matches</p>
<p className="text-sm text-gray-500">Matchups</p>
<p className="text-2xl font-bold text-gray-900">
{matches.length}
</p>
@@ -287,7 +253,6 @@ export default async function TournamentDetailPage({ params }: PageProps) {
{/* Teams Section */}
<TeamsSection
tournamentId={tournament.id}
teams={tournament.teams}
participants={tournament.participants.map(p => ({
id: p.player.id,
name: p.player.name,
@@ -317,8 +282,8 @@ export default async function TournamentDetailPage({ params }: PageProps) {
{match.playedAt?.toLocaleDateString()}
</p>
<p className="font-medium">
{match.team1P1.name} + {match.team1P2.name} vs{" "}
{match.team2P1.name} + {match.team2P2.name}
{match.player1P1?.name} + {match.player1P2?.name} vs{" "}
{match.player2P1?.name} + {match.player2P2?.name}
</p>
</div>
<div className="text-right">
@@ -38,10 +38,10 @@ export default async function TournamentResultsPage({ params }: PageProps) {
const matches = await prisma.match.findMany({
where: { eventId: tournamentId },
include: {
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
},
orderBy: { playedAt: "desc" },
})
@@ -114,8 +114,8 @@ export default async function TournamentResultsPage({ params }: PageProps) {
{match.playedAt?.toLocaleDateString()}
</p>
<p className="font-medium">
{match.team1P1.name} + {match.team1P2.name} vs{" "}
{match.team2P1.name} + {match.team2P2.name}
{match.player1P1?.name} + {match.player1P2?.name} vs{" "}
{match.player2P1?.name} + {match.player2P2?.name}
</p>
</div>
<div className="text-right flex items-center">
@@ -34,23 +34,15 @@ export default async function TournamentSchedulePage({ params }: PageProps) {
const tournament = await prisma.event.findUnique({
where: { id: tournamentId },
include: {
teams: {
include: {
player1: true,
player2: true,
},
},
rounds: {
orderBy: { roundNumber: "asc" },
include: {
bracketMatchups: {
include: {
team1: {
include: { player1: true, player2: true },
},
team2: {
include: { player1: true, player2: true },
},
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
match: true,
},
},
@@ -94,7 +86,7 @@ export default async function TournamentSchedulePage({ params }: PageProps) {
<div className="bg-white shadow rounded-lg p-6 mb-6">
<h1 className="text-2xl font-bold text-gray-900">Tournament Schedule</h1>
<p className="text-gray-500 mt-1">
{tournament.name} {tournament.teams.length} teams
{tournament.name}
</p>
</div>
@@ -106,7 +98,7 @@ export default async function TournamentSchedulePage({ params }: PageProps) {
</h2>
<ScheduleGenerator
tournamentId={tournamentId}
teamCount={tournament.teams.length}
teamCount={0}
/>
</div>
)}
@@ -128,11 +120,11 @@ export default async function TournamentSchedulePage({ params }: PageProps) {
) : (
<div className="space-y-3">
{round.bracketMatchups.map((matchup) => {
const team1Name = matchup.team1
? `${matchup.team1.player1.name} + ${matchup.team1.player2.name}`
const team1Name = matchup.player1P1 && matchup.player1P2
? `${matchup.player1P1.name} + ${matchup.player1P2.name}`
: "TBD"
const team2Name = matchup.team2
? `${matchup.team2.player1.name} + ${matchup.team2.player2.name}`
const team2Name = matchup.player2P1 && matchup.player2P2
? `${matchup.player2P1.name} + ${matchup.player2P2.name}`
: "TBD"
return (
@@ -208,7 +200,7 @@ export default async function TournamentSchedulePage({ params }: PageProps) {
</h2>
<ScheduleGenerator
tournamentId={tournamentId}
teamCount={tournament.teams.length}
teamCount={0}
/>
</div>
)}
+48 -40
View File
@@ -22,10 +22,10 @@ export default async function MatchDetailPage({ params }: PageProps) {
const match = await prisma.match.findUnique({
where: { id: matchId },
include: {
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
event: true,
eloSnapshots: {
include: {
@@ -93,13 +93,13 @@ export default async function MatchDetailPage({ params }: PageProps) {
<div className="absolute top-0 left-0 right-0 h-1/2 flex flex-col justify-end items-center pb-8">
<div className="text-center bg-white/80 rounded-lg px-3 py-2 shadow-sm -mt-[20px]">
<p className="text-base font-semibold text-amber-900">
{match.team1P1.name}
{match.player1P1?.name}
</p>
<p className="text-xs text-amber-700">
Elo: {match.team1P1.currentElo}
{eloChanges[match.team1P1.id] !== undefined && (
<span className={eloChanges[match.team1P1.id] >= 0 ? "text-green-600 ml-1" : "text-red-600 ml-1"}>
({eloChanges[match.team1P1.id] >= 0 ? "+" : ""}{eloChanges[match.team1P1.id]})
Elo: {match.player1P1?.currentElo}
{match.player1P1 && eloChanges[match.player1P1.id] !== undefined && (
<span className={eloChanges[match.player1P1.id] >= 0 ? "text-green-600 ml-1" : "text-red-600 ml-1"}>
({eloChanges[match.player1P1.id] >= 0 ? "+" : ""}{eloChanges[match.player1P1.id]})
</span>
)}
</p>
@@ -112,13 +112,13 @@ export default async function MatchDetailPage({ params }: PageProps) {
<div className="text-xs text-amber-600 mb-2 font-medium">Team 1</div>
<div className="text-center bg-white/80 rounded-lg px-3 py-2 shadow-sm mt-[10px]">
<p className="text-base font-semibold text-amber-900">
{match.team1P2.name}
{match.player1P2?.name}
</p>
<p className="text-xs text-amber-700">
Elo: {match.team1P2.currentElo}
{eloChanges[match.team1P2.id] !== undefined && (
<span className={eloChanges[match.team1P2.id] >= 0 ? "text-green-600 ml-1" : "text-red-600 ml-1"}>
({eloChanges[match.team1P2.id] >= 0 ? "+" : ""}{eloChanges[match.team1P2.id]})
Elo: {match.player1P2?.currentElo}
{match.player1P2 && eloChanges[match.player1P2.id] !== undefined && (
<span className={eloChanges[match.player1P2.id] >= 0 ? "text-green-600 ml-1" : "text-red-600 ml-1"}>
({eloChanges[match.player1P2.id] >= 0 ? "+" : ""}{eloChanges[match.player1P2.id]})
</span>
)}
</p>
@@ -129,13 +129,13 @@ export default async function MatchDetailPage({ params }: PageProps) {
<div className="absolute left-0 top-0 bottom-0 w-1/2 flex flex-col justify-center items-center pl-8">
<div className="text-center bg-white/80 rounded-lg px-3 py-2 shadow-sm rotate-[-90deg] -ml-[20px]">
<p className="text-sm font-semibold text-red-900">
{match.team2P1.name}
{match.player2P1?.name}
</p>
<p className="text-[11px] text-red-700">
Elo: {match.team2P1.currentElo}
{eloChanges[match.team2P1.id] !== undefined && (
<span className={eloChanges[match.team2P1.id] >= 0 ? "text-green-600" : "text-red-600"}>
({eloChanges[match.team2P1.id] >= 0 ? "+" : ""}{eloChanges[match.team2P1.id]})
Elo: {match.player2P1?.currentElo}
{match.player2P1 && eloChanges[match.player2P1.id] !== undefined && (
<span className={eloChanges[match.player2P1.id] >= 0 ? "text-green-600" : "text-red-600"}>
({eloChanges[match.player2P1.id] >= 0 ? "+" : ""}{eloChanges[match.player2P1.id]})
</span>
)}
</p>
@@ -146,13 +146,13 @@ export default async function MatchDetailPage({ params }: PageProps) {
<div className="absolute right-0 top-0 bottom-0 w-1/2 flex flex-col justify-center items-center pr-8">
<div className="text-center bg-white/80 rounded-lg px-3 py-2 shadow-sm rotate-[90deg] -mr-[20px]">
<p className="text-sm font-semibold text-red-900">
{match.team2P2.name}
{match.player2P2?.name}
</p>
<p className="text-[11px] text-red-700">
Elo: {match.team2P2.currentElo}
{eloChanges[match.team2P2.id] !== undefined && (
<span className={eloChanges[match.team2P2.id] >= 0 ? "text-green-600" : "text-red-600"}>
({eloChanges[match.team2P2.id] >= 0 ? "+" : ""}{eloChanges[match.team2P2.id]})
Elo: {match.player2P2?.currentElo}
{match.player2P2 && eloChanges[match.player2P2.id] !== undefined && (
<span className={eloChanges[match.player2P2.id] >= 0 ? "text-green-600" : "text-red-600"}>
({eloChanges[match.player2P2.id] >= 0 ? "+" : ""}{eloChanges[match.player2P2.id]})
</span>
)}
</p>
@@ -246,16 +246,20 @@ export default async function MatchDetailPage({ params }: PageProps) {
<h3 className="font-medium text-amber-900 mb-3">Team 1</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span>{match.team1P1.name}</span>
<span className={eloChanges[match.team1P1.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.team1P1.id] >= 0 ? "+" : ""}{eloChanges[match.team1P1.id]}
</span>
<span>{match.player1P1?.name}</span>
{match.player1P1 && (
<span className={eloChanges[match.player1P1.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.player1P1.id] >= 0 ? "+" : ""}{eloChanges[match.player1P1.id]}
</span>
)}
</div>
<div className="flex justify-between items-center">
<span>{match.team1P2.name}</span>
<span className={eloChanges[match.team1P2.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.team1P2.id] >= 0 ? "+" : ""}{eloChanges[match.team1P2.id]}
</span>
<span>{match.player1P2?.name}</span>
{match.player1P2 && (
<span className={eloChanges[match.player1P2.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.player1P2.id] >= 0 ? "+" : ""}{eloChanges[match.player1P2.id]}
</span>
)}
</div>
</div>
</div>
@@ -265,16 +269,20 @@ export default async function MatchDetailPage({ params }: PageProps) {
<h3 className="font-medium text-red-900 mb-3">Team 2</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span>{match.team2P1.name}</span>
<span className={eloChanges[match.team2P1.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.team2P1.id] >= 0 ? "+" : ""}{eloChanges[match.team2P1.id]}
</span>
<span>{match.player2P1?.name}</span>
{match.player2P1 && (
<span className={eloChanges[match.player2P1.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.player2P1.id] >= 0 ? "+" : ""}{eloChanges[match.player2P1.id]}
</span>
)}
</div>
<div className="flex justify-between items-center">
<span>{match.team2P2.name}</span>
<span className={eloChanges[match.team2P2.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.team2P2.id] >= 0 ? "+" : ""}{eloChanges[match.team2P2.id]}
</span>
<span>{match.player2P2?.name}</span>
{match.player2P2 && (
<span className={eloChanges[match.player2P2.id] >= 0 ? "text-green-600" : "text-red-600"}>
{eloChanges[match.player2P2.id] >= 0 ? "+" : ""}{eloChanges[match.player2P2.id]}
</span>
)}
</div>
</div>
</div>
+6 -6
View File
@@ -25,10 +25,10 @@ export default async function MatchesListPage() {
orderBy: { createdAt: "desc" },
take: 50,
include: {
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
event: true,
},
});
@@ -84,10 +84,10 @@ export default async function MatchesListPage() {
#{match.id}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{match.team1P1.name} & {match.team1P2.name}
{match.player1P1?.name} & {match.player1P2?.name}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{match.team2P1.name} & {match.team2P2.name}
{match.player2P1?.name} & {match.player2P2?.name}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<span className="font-medium">{match.team1Score}</span>
+6 -6
View File
@@ -24,10 +24,10 @@ export default async function Home() {
include: {
matches: {
include: {
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
},
orderBy: { playedAt: "desc" },
},
@@ -178,7 +178,7 @@ export default async function Home() {
<div className="flex justify-between items-center">
<div className="flex-1 text-center">
<div className="text-sm font-medium text-gray-900">
{match.team1P1.name} & {match.team1P2.name}
{match.player1P1?.name} & {match.player1P2?.name}
</div>
<div className="text-lg font-bold text-gray-800">
{match.team1Score}
@@ -187,7 +187,7 @@ export default async function Home() {
<div className="px-3 text-gray-500">vs</div>
<div className="flex-1 text-center">
<div className="text-sm font-medium text-gray-900">
{match.team2P1.name} & {match.team2P2.name}
{match.player2P1?.name} & {match.player2P2?.name}
</div>
<div className="text-lg font-bold text-gray-800">
{match.team2Score}
+25 -23
View File
@@ -64,17 +64,17 @@ export default async function PlayerProfilePage({ params }: PageProps) {
const recentMatches = await prisma.match.findMany({
where: {
OR: [
{ team1P1Id: playerId },
{ team1P2Id: playerId },
{ team2P1Id: playerId },
{ team2P2Id: playerId },
{ player1P1Id: playerId },
{ player1P2Id: playerId },
{ player2P1Id: playerId },
{ player2P2Id: playerId },
],
},
include: {
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
event: true,
},
orderBy: { playedAt: "desc" },
@@ -247,18 +247,18 @@ export default async function PlayerProfilePage({ params }: PageProps) {
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{recentMatches.map((match) => {
const isTeam1 = match.team1P1Id === playerId || match.team1P2Id === playerId;
const isTeam1 = match.player1P1Id === playerId || match.player1P2Id === 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);
? (match.player1P1Id === playerId ? match.player1P2 : match.player1P1)
: (match.player2P1Id === playerId ? match.player2P2 : match.player2P1);
const opponents = isTeam1
? [match.team2P1, match.team2P2]
: [match.team1P1, match.team1P2];
? [match.player2P1, match.player2P2]
: [match.player1P1, match.player1P2];
return (
<tr key={match.id} className="hover:bg-gray-50">
@@ -276,21 +276,23 @@ export default async function PlayerProfilePage({ params }: PageProps) {
{match.event?.name || "N/A"}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<Link
href={`/players/${teammate.id}/profile`}
className="text-green-600 hover:text-green-900"
>
{teammate.name}
</Link>
{teammate && (
<Link
href={`/players/${teammate.id}/profile`}
className="text-green-600 hover:text-green-900"
>
{teammate.name}
</Link>
)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{opponents.map((opponent, index) => (
<span key={opponent.id}>
{opponents.filter(o => o !== null).map((opponent, index) => (
<span key={opponent?.id}>
<Link
href={`/players/${opponent.id}/profile`}
href={`/players/${opponent?.id}/profile`}
className="text-green-600 hover:text-green-900"
>
{opponent.name}
{opponent?.name}
</Link>
{index < opponents.length - 1 ? ", " : ""}
</span>
+27 -33
View File
@@ -27,10 +27,10 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
where: { playedAt: { gte: new Date() } },
include: {
event: true,
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
},
orderBy: { playedAt: "asc" },
},
@@ -38,10 +38,10 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
where: { playedAt: { gte: new Date() } },
include: {
event: true,
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
},
orderBy: { playedAt: "asc" },
},
@@ -49,10 +49,10 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
where: { playedAt: { gte: new Date() } },
include: {
event: true,
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
},
orderBy: { playedAt: "asc" },
},
@@ -60,10 +60,10 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
where: { playedAt: { gte: new Date() } },
include: {
event: true,
team1P1: true,
team1P2: true,
team2P1: true,
team2P2: true,
player1P1: true,
player1P2: true,
player2P1: true,
player2P2: true,
},
orderBy: { playedAt: "asc" },
},
@@ -94,12 +94,6 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
},
include: {
participants: true,
teams: {
include: {
player1: true,
player2: true,
},
},
},
})
@@ -125,13 +119,13 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
<div className="space-y-4">
{upcomingMatches.map((match) => {
const team1Players = [
match.team1P1.name,
match.team1P2.name,
].join(" + ")
match.player1P1?.name,
match.player1P2?.name,
].filter(Boolean).join(" + ")
const team2Players = [
match.team2P1.name,
match.team2P2.name,
].join(" + ")
match.player2P1?.name,
match.player2P2?.name,
].filter(Boolean).join(" + ")
return (
<div
@@ -171,9 +165,9 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
) : (
<div className="space-y-4">
{activeTournaments.map((tournament) => {
const playerTeam = tournament.teams.find(
(team) =>
team.player1Id === playerId || team.player2Id === playerId
// Since teams are now ephemeral, just check if player is a participant
const isParticipant = tournament.participants.some(
(p) => p.playerId === playerId
)
return (
@@ -192,9 +186,9 @@ export default async function PlayerSchedulePage({ params }: PageProps) {
<p className="text-sm text-gray-500">
{tournament.format} - {tournament.status}
</p>
{playerTeam && (
{isParticipant && (
<p className="text-sm text-gray-600">
Team: {playerTeam.player1.name} + {playerTeam.player2.name}
Participant in tournament
</p>
)}
</div>