fix: submission round completion %, document details, project teams UX
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m32s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m32s
- Fix 0% completion on SUBMISSION pipeline cards — now based on teams with uploads / total projects instead of evaluation completions - Add page count, detected language, and non-English warning indicator to Recent Documents list items - Add project avatar (logo) to document and project list rows - Make document rows clickable into project detail page - Remove team name from project list (none have names), show country only - Rename "Teams Submitted" to "Teams with Uploads" for clarity - Add "See all" link to Projects section → /observer/projects - Rename section from "Project Teams" to "Projects" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -887,6 +887,7 @@ export const analyticsRouter = router({
|
||||
allAssignmentCounts,
|
||||
allCompletedEvals,
|
||||
allDistinctJurors,
|
||||
allSubmissionFileCounts,
|
||||
] = await Promise.all([
|
||||
ctx.prisma.projectRoundState.groupBy({
|
||||
by: ['roundId', 'state'],
|
||||
@@ -910,6 +911,15 @@ export const analyticsRouter = router({
|
||||
by: ['roundId', 'userId'],
|
||||
where: { roundId: { in: roundIds } },
|
||||
}),
|
||||
// Count distinct projects with files per round (for SUBMISSION completion)
|
||||
ctx.prisma.$queryRaw<{ roundId: string; teamsWithFiles: bigint; totalFiles: bigint }[]>`
|
||||
SELECT "roundId",
|
||||
COUNT(DISTINCT "projectId")::bigint as "teamsWithFiles",
|
||||
COUNT(id)::bigint as "totalFiles"
|
||||
FROM "ProjectFile"
|
||||
WHERE "roundId" = ANY(${roundIds})
|
||||
GROUP BY "roundId"
|
||||
`,
|
||||
])
|
||||
|
||||
// Build lookup maps
|
||||
@@ -935,16 +945,34 @@ export const analyticsRouter = router({
|
||||
jurorCountByRound.set(j.roundId, (jurorCountByRound.get(j.roundId) || 0) + 1)
|
||||
}
|
||||
|
||||
const submissionFilesByRound = new Map<string, { teamsWithFiles: number; totalFiles: number }>()
|
||||
for (const sf of allSubmissionFileCounts) {
|
||||
submissionFilesByRound.set(sf.roundId, {
|
||||
teamsWithFiles: Number(sf.teamsWithFiles),
|
||||
totalFiles: Number(sf.totalFiles),
|
||||
})
|
||||
}
|
||||
|
||||
const roundOverviews = rounds.map((round) => {
|
||||
const stateBreakdown = statesByRound.get(round.id) || []
|
||||
const totalProjects = stateBreakdown.reduce((sum, ps) => sum + ps.count, 0)
|
||||
const totalAssignments = assignmentCountByRound.get(round.id) || 0
|
||||
const completedEvaluations = completedEvalsByRound.get(round.id) || 0
|
||||
const completionRate = (round.status === 'ROUND_CLOSED' || round.status === 'ROUND_ARCHIVED')
|
||||
? 100
|
||||
: totalAssignments > 0
|
||||
? Math.min(100, Math.round((completedEvaluations / totalAssignments) * 100))
|
||||
const submissionFiles = submissionFilesByRound.get(round.id)
|
||||
|
||||
let completionRate: number
|
||||
if (round.status === 'ROUND_CLOSED' || round.status === 'ROUND_ARCHIVED') {
|
||||
completionRate = 100
|
||||
} else if (round.roundType === 'SUBMISSION') {
|
||||
// For submission rounds, completion = teams that uploaded at least one file / total projects
|
||||
completionRate = totalProjects > 0 && submissionFiles
|
||||
? Math.min(100, Math.round((submissionFiles.teamsWithFiles / totalProjects) * 100))
|
||||
: 0
|
||||
} else if (totalAssignments > 0) {
|
||||
completionRate = Math.min(100, Math.round((completedEvaluations / totalAssignments) * 100))
|
||||
} else {
|
||||
completionRate = 0
|
||||
}
|
||||
|
||||
return {
|
||||
roundId: round.id,
|
||||
@@ -2143,8 +2171,12 @@ export const analyticsRouter = router({
|
||||
fileName: true,
|
||||
fileType: true,
|
||||
createdAt: true,
|
||||
pageCount: true,
|
||||
detectedLang: true,
|
||||
langConfidence: true,
|
||||
analyzedAt: true,
|
||||
project: {
|
||||
select: { id: true, title: true, teamName: true },
|
||||
select: { id: true, title: true, teamName: true, logoKey: true },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user