From ba7f068b1e697602bb6bff9e03efa31109fa3a73 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 27 Feb 2026 11:08:30 +0100 Subject: [PATCH] fix: show project title, team & country in ranking rows instead of truncated IDs Adds getProjectStates query to build a projectInfoMap lookup. Each row now shows the project title, team name, and country. Also renames "Pass" label to "Yes" to match the binary yes/no vote semantics. Co-Authored-By: Claude Opus 4.6 --- .../admin/round/ranking-dashboard.tsx | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/components/admin/round/ranking-dashboard.tsx b/src/components/admin/round/ranking-dashboard.tsx index b61d5b1..1bd85c4 100644 --- a/src/components/admin/round/ranking-dashboard.tsx +++ b/src/components/admin/round/ranking-dashboard.tsx @@ -59,10 +59,17 @@ type RankingDashboardProps = { roundId: string } +type ProjectInfo = { + title: string + teamName: string | null + country: string | null +} + type SortableProjectRowProps = { projectId: string currentRank: number entry: RankedProjectEntry | undefined + projectInfo: ProjectInfo | undefined onSelect: () => void isSelected: boolean } @@ -73,6 +80,7 @@ function SortableProjectRow({ projectId, currentRank, entry, + projectInfo, onSelect, isSelected, }: SortableProjectRowProps) { @@ -128,11 +136,17 @@ function SortableProjectRow({ )} - {/* Project identifier */} + {/* Project info */}

- Project …{projectId.slice(-6)} + {projectInfo?.title ?? `Project …${projectId.slice(-6)}`}

+ {projectInfo?.teamName && ( +

+ {projectInfo.teamName} + {projectInfo.country ? ` · ${projectInfo.country}` : ''} +

+ )}
{/* Stats */} @@ -147,8 +161,8 @@ function SortableProjectRow({ Avg {entry.avgGlobalScore.toFixed(1)} )} - - Pass {Math.round(entry.passRate * 100)}% + + Yes {Math.round(entry.passRate * 100)}% {entry.evaluatorCount} juror{entry.evaluatorCount !== 1 ? 's' : ''} @@ -197,6 +211,10 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran { enabled: !!latestSnapshotId }, ) + const { data: projectStates } = trpc.roundEngine.getProjectStates.useQuery( + { roundId }, + ) + const { data: projectDetail, isLoading: detailLoading } = trpc.project.getFullDetail.useQuery( { id: selectedProjectId! }, { enabled: !!selectedProjectId }, @@ -253,6 +271,20 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran return map }, [snapshot]) + // ─── projectInfoMap (O(1) lookup by projectId) ──────────────────────────── + const projectInfoMap = useMemo(() => { + const map = new Map() + if (!projectStates) return map + for (const ps of projectStates) { + map.set(ps.project.id, { + title: ps.project.title, + teamName: ps.project.teamName, + country: ps.project.country, + }) + } + return map + }, [projectStates]) + // ─── localOrder init (once, with useRef guard) ──────────────────────────── useEffect(() => { if (!initialized.current && snapshot) { @@ -448,6 +480,7 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran projectId={projectId} currentRank={index + 1} entry={rankingMap.get(projectId)} + projectInfo={projectInfoMap.get(projectId)} onSelect={() => setSelectedProjectId(projectId)} isSelected={selectedProjectId === projectId} />