From 664a6825850413af83660ca56c9dd48decc20115 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 27 Apr 2026 13:23:29 +0200 Subject: [PATCH] feat: side panel shows raw + balanced averages, list drops delta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the per-row '⇢ X.X' annotation from the ranking list — the list view stays clean. The side panel's stats area gains a combined Avg Score card that shows Raw and Balanced side-by-side, with the active one (per the round's toggle) bolded and tagged 'used for ranking'. Pass Rate and Evaluators move below into a 2-col grid. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../admin/round/ranking-dashboard.tsx | 91 +++++++++---------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/src/components/admin/round/ranking-dashboard.tsx b/src/components/admin/round/ranking-dashboard.tsx index a3eec6c..4b29132 100644 --- a/src/components/admin/round/ranking-dashboard.tsx +++ b/src/components/admin/round/ranking-dashboard.tsx @@ -83,7 +83,6 @@ type SortableProjectRowProps = { entry: (RankedProjectEntry & { originalIndex?: number }) | undefined projectInfo: ProjectInfo | undefined jurorScores: JurorScore[] | undefined - balancedScore: number | null onSelect: () => void isSelected: boolean originalRank: number | undefined // from snapshotOrder — always in sync with localOrder @@ -97,7 +96,6 @@ function SortableProjectRow({ entry, projectInfo, jurorScores, - balancedScore, onSelect, isSelected, originalRank, @@ -202,27 +200,6 @@ function SortableProjectRow({ ) : null} - {/* Raw + balanced averages shown side by side */} - {entry?.avgGlobalScore !== null && entry?.avgGlobalScore !== undefined && jurorScores && jurorScores.length > 1 && ( -
- - {entry.avgGlobalScore.toFixed(1)} - - {balancedScore != null && Math.abs(balancedScore - entry.avgGlobalScore) >= 0.05 && ( - entry.avgGlobalScore - ? 'bg-emerald-50 text-emerald-700 border-emerald-200' - : 'bg-amber-50 text-amber-700 border-amber-200', - )} - > - ⇢ {balancedScore.toFixed(1)} - - )} -
- )} - {/* Advance decision indicator */}
setSelectedProjectId(projectId)} isSelected={selectedProjectId === projectId} originalRank={hasReorders ? snapshotOrder[projectId] : undefined} @@ -1075,31 +1051,50 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
- {/* Stats summary */} - {projectDetail.stats && ( -
-
-

Avg Score

-

- {projectDetail.stats.averageGlobalScore?.toFixed(1) ?? '—'} -

+ {/* Stats summary: combined Avg card with Raw + Balanced side-by-side */} + {projectDetail.stats && (() => { + const raw = selectedProjectId + ? evalScores?.balanced[selectedProjectId]?.rawAverage ?? null + : null + const balanced = selectedProjectId + ? evalScores?.balanced[selectedProjectId]?.balancedAverage ?? null + : null + return ( +
+
+

Avg Score

+
+
+ Raw + {raw != null ? raw.toFixed(1) : '—'} + {!useBalanced && ← used for ranking} +
+
+ Balanced + {balanced != null ? balanced.toFixed(1) : '—'} + {useBalanced && ← used for ranking} +
+
+
+
+
+

Pass Rate

+

+ {projectDetail.stats.totalEvaluations > 0 + ? `${Math.round((projectDetail.stats.yesVotes / projectDetail.stats.totalEvaluations) * 100)}%` + : '—'} +

+
+
+

Evaluators

+

+ {projectDetail.stats.totalEvaluations} +

+
+
-
-

Pass Rate

-

- {projectDetail.stats.totalEvaluations > 0 - ? `${Math.round((projectDetail.stats.yesVotes / projectDetail.stats.totalEvaluations) * 100)}%` - : '—'} -

-
-
-

Evaluators

-

- {projectDetail.stats.totalEvaluations} -

-
-
- )} + ) + })()} {/* Per-juror evaluations */}