Show award-routed projects in filtering stats and results table
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled

- Stats cards show new 'Award Track' card with count of confirmed
  SEPARATE_POOL shortlisted projects
- Passed card shows breakdown (main + award) when awards are routed
- Results table shows award badge on projects routed to award tracks
- getResults query includes confirmed award eligibility data per project

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt
2026-02-18 10:25:47 +01:00
parent 6e9fcda45a
commit 35f30af7ce
2 changed files with 64 additions and 9 deletions

View File

@@ -686,7 +686,7 @@ export function FilteringDashboard({ competitionId, roundId }: FilteringDashboar
))} ))}
</div> </div>
) : stats && stats.total > 0 ? ( ) : stats && stats.total > 0 ? (
<div className="grid gap-4 grid-cols-2 lg:grid-cols-5"> <div className="grid gap-4 grid-cols-2 lg:grid-cols-6">
<Card> <Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Total</CardTitle> <CardTitle className="text-sm font-medium">Total</CardTitle>
@@ -706,6 +706,11 @@ export function FilteringDashboard({ competitionId, roundId }: FilteringDashboar
<div className="text-2xl font-bold text-green-700">{stats.passed}</div> <div className="text-2xl font-bold text-green-700">{stats.passed}</div>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
{stats.total > 0 ? `${((stats.passed / stats.total) * 100).toFixed(0)}%` : '0%'} {stats.total > 0 ? `${((stats.passed / stats.total) * 100).toFixed(0)}%` : '0%'}
{stats.routedToAwards > 0 && (
<span className="block text-amber-600 mt-0.5">
{stats.passed - stats.routedToAwards} main + {stats.routedToAwards} award
</span>
)}
</p> </p>
</CardContent> </CardContent>
</Card> </Card>
@@ -741,6 +746,18 @@ export function FilteringDashboard({ competitionId, roundId }: FilteringDashboar
<p className="text-xs text-muted-foreground">Manual changes</p> <p className="text-xs text-muted-foreground">Manual changes</p>
</CardContent> </CardContent>
</Card> </Card>
{stats.routedToAwards > 0 && (
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Award Track</CardTitle>
<Award className="h-4 w-4 text-amber-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-amber-700">{stats.routedToAwards}</div>
<p className="text-xs text-muted-foreground">Routed to awards</p>
</CardContent>
</Card>
)}
</div> </div>
) : null} ) : null}
@@ -878,13 +895,21 @@ export function FilteringDashboard({ competitionId, roundId }: FilteringDashboar
<ChevronDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" /> <ChevronDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
)} )}
<div className="min-w-0"> <div className="min-w-0">
<div className="flex items-center gap-1.5">
<Link <Link
href={`/admin/projects/${result.projectId}` as Route} href={`/admin/projects/${result.projectId}` as Route}
className="font-medium truncate block hover:underline text-foreground" className="font-medium truncate hover:underline text-foreground"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
{result.project?.title || 'Unknown'} {result.project?.title || 'Unknown'}
</Link> </Link>
{result.project?.awardEligibilities?.length > 0 && (
<Badge variant="outline" className="text-[10px] px-1.5 py-0 bg-amber-50 text-amber-700 border-amber-200 shrink-0">
<Award className="h-2.5 w-2.5 mr-0.5" />
{result.project.awardEligibilities[0].award.name}
</Badge>
)}
</div>
<p className="text-xs text-muted-foreground truncate"> <p className="text-xs text-muted-foreground truncate">
{result.project?.teamName} {result.project?.teamName}
{result.project?.country && ` \u00b7 ${result.project.country}`} {result.project?.country && ` \u00b7 ${result.project.country}`}

View File

@@ -877,6 +877,16 @@ export const filteringRouter = router({
teamName: true, teamName: true,
competitionCategory: true, competitionCategory: true,
country: true, country: true,
awardEligibilities: {
where: {
shortlisted: true,
confirmedAt: { not: null },
award: { eligibilityMode: 'SEPARATE_POOL' },
},
select: {
award: { select: { name: true } },
},
},
}, },
}, },
overriddenByUser: { overriddenByUser: {
@@ -936,7 +946,27 @@ export const filteringRouter = router({
}), }),
]) ])
return { passed, filteredOut, flagged, overridden, total: passed + filteredOut + flagged } // Count projects routed to SEPARATE_POOL award tracks (confirmed shortlist)
const round = await ctx.prisma.round.findUnique({
where: { id: input.roundId },
select: { competitionId: true },
})
let routedToAwards = 0
if (round?.competitionId) {
routedToAwards = await ctx.prisma.awardEligibility.count({
where: {
award: {
competitionId: round.competitionId,
eligibilityMode: 'SEPARATE_POOL',
},
shortlisted: true,
confirmedAt: { not: null },
},
})
}
return { passed, filteredOut, flagged, overridden, routedToAwards, total: passed + filteredOut + flagged }
}), }),
/** /**