From 91563f3f4779142c8db07bae53be2e693eeefcd1 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 23 Feb 2026 20:38:43 +0100 Subject: [PATCH] Add Reviews column to Projects tab showing evaluation submission progress Backend: getProjectRoundStates now includes assignment counts and submitted evaluation counts per project. Frontend: new Reviews column shows X/Y (submitted/total) with green highlight when all reviews are complete. Co-Authored-By: Claude Opus 4.6 --- .../admin/round/project-states-table.tsx | 17 +++++++++-- src/server/services/round-engine.ts | 28 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/components/admin/round/project-states-table.tsx b/src/components/admin/round/project-states-table.tsx index e8a534c..4f0b614 100644 --- a/src/components/admin/round/project-states-table.tsx +++ b/src/components/admin/round/project-states-table.tsx @@ -328,7 +328,7 @@ export function ProjectStatesTable({ competitionId, roundId }: ProjectStatesTabl {/* Table */}
{/* Header */} -
+
0 && filtered.every((ps: any) => selectedIds.has(ps.projectId))} @@ -339,6 +339,7 @@ export function ProjectStatesTable({ competitionId, roundId }: ProjectStatesTabl
Category
Country
State
+
Reviews
Entered
@@ -347,10 +348,13 @@ export function ProjectStatesTable({ competitionId, roundId }: ProjectStatesTabl {filtered.map((ps: any) => { const cfg = stateConfig[ps.state as ProjectState] || stateConfig.PENDING const StateIcon = cfg.icon + const total = ps.totalAssignments ?? 0 + const submitted = ps.submittedCount ?? 0 + const allDone = total > 0 && submitted === total return (
+
+ {total > 0 ? ( + + {submitted}/{total} + + ) : ( + + )} +
{ps.enteredAt ? new Date(ps.enteredAt).toLocaleDateString() : '—'}
diff --git a/src/server/services/round-engine.ts b/src/server/services/round-engine.ts index 27c4c0a..9fc75de 100644 --- a/src/server/services/round-engine.ts +++ b/src/server/services/round-engine.ts @@ -703,7 +703,7 @@ export async function getProjectRoundStates( roundId: string, prisma: PrismaClient | any, ) { - return prisma.projectRoundState.findMany({ + const states = await prisma.projectRoundState.findMany({ where: { roundId }, include: { project: { @@ -714,11 +714,37 @@ export async function getProjectRoundStates( competitionCategory: true, country: true, status: true, + assignments: { + where: { roundId }, + select: { + id: true, + isCompleted: true, + evaluation: { select: { status: true } }, + }, + }, }, }, }, orderBy: { enteredAt: 'desc' }, }) + + // Compute evaluation progress per project + return states.map((ps: any) => { + const assignments = ps.project?.assignments ?? [] + const totalAssignments = assignments.length + const submittedCount = assignments.filter( + (a: any) => a.evaluation?.status === 'SUBMITTED' + ).length + return { + ...ps, + totalAssignments, + submittedCount, + project: { + ...ps.project, + assignments: undefined, // strip raw assignments from response + }, + } + }) } export async function getProjectRoundState(