Add Reviews column to Projects tab showing evaluation submission progress
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m36s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m36s
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 <noreply@anthropic.com>
This commit is contained in:
@@ -328,7 +328,7 @@ export function ProjectStatesTable({ competitionId, roundId }: ProjectStatesTabl
|
||||
{/* Table */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
{/* Header */}
|
||||
<div className="grid grid-cols-[40px_1fr_140px_160px_120px_100px_48px] gap-2 px-4 py-2.5 bg-muted/40 text-xs font-medium text-muted-foreground border-b">
|
||||
<div className="grid grid-cols-[40px_1fr_140px_160px_120px_80px_100px_48px] gap-2 px-4 py-2.5 bg-muted/40 text-xs font-medium text-muted-foreground border-b">
|
||||
<div>
|
||||
<Checkbox
|
||||
checked={filtered.length > 0 && filtered.every((ps: any) => selectedIds.has(ps.projectId))}
|
||||
@@ -339,6 +339,7 @@ export function ProjectStatesTable({ competitionId, roundId }: ProjectStatesTabl
|
||||
<div>Category</div>
|
||||
<div>Country</div>
|
||||
<div>State</div>
|
||||
<div>Reviews</div>
|
||||
<div>Entered</div>
|
||||
<div />
|
||||
</div>
|
||||
@@ -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 (
|
||||
<div
|
||||
key={ps.id}
|
||||
className="grid grid-cols-[40px_1fr_140px_160px_120px_100px_48px] gap-2 px-4 py-3 items-center border-b last:border-b-0 hover:bg-muted/30 text-sm"
|
||||
className="grid grid-cols-[40px_1fr_140px_160px_120px_80px_100px_48px] gap-2 px-4 py-3 items-center border-b last:border-b-0 hover:bg-muted/30 text-sm"
|
||||
>
|
||||
<div>
|
||||
<Checkbox
|
||||
@@ -381,6 +385,15 @@ export function ProjectStatesTable({ competitionId, roundId }: ProjectStatesTabl
|
||||
{cfg.label}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="text-xs tabular-nums">
|
||||
{total > 0 ? (
|
||||
<span className={allDone ? 'text-green-600 font-medium' : 'text-muted-foreground'}>
|
||||
{submitted}/{total}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-muted-foreground">—</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{ps.enteredAt ? new Date(ps.enteredAt).toLocaleDateString() : '—'}
|
||||
</div>
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user