diff --git a/src/components/admin/round/finalization-tab.tsx b/src/components/admin/round/finalization-tab.tsx index 8ffaf70..4da11bd 100644 --- a/src/components/admin/round/finalization-tab.tsx +++ b/src/components/admin/round/finalization-tab.tsx @@ -41,6 +41,7 @@ import { Send, Eye, } from 'lucide-react' +import Link from 'next/link' import { cn } from '@/lib/utils' import { projectStateConfig } from '@/lib/round-config' import { EmailPreviewDialog } from './email-preview-dialog' @@ -204,8 +205,12 @@ export function FinalizationTab({ roundId, roundStatus }: FinalizationTabProps) batchUpdate.mutate({ roundId, outcomes }) } + // Does this round have document requirements to show? + const hasDocColumn = (summary?.roundType === 'SUBMISSION' || summary?.roundType === 'INTAKE') && + summary?.projects.some((p) => p.documentsRequired != null && p.documentsRequired > 0) + // Column count for colSpan - const colCount = (summary?.isFinalized ? 0 : 1) + 4 + (summary?.roundType === 'EVALUATION' ? 1 : 0) + 1 + const colCount = (summary?.isFinalized ? 0 : 1) + 4 + (summary?.roundType === 'EVALUATION' ? 1 : 0) + (hasDocColumn ? 1 : 0) + 1 // Shared row renderer const renderProjectRow = (project: (typeof filteredProjects)[number]) => ( @@ -225,7 +230,9 @@ export function FinalizationTab({ roundId, roundStatus }: FinalizationTabProps) )} -
{project.title}
+ + {project.title} + {project.teamName && (
{project.teamName}
)} @@ -241,6 +248,20 @@ export function FinalizationTab({ roundId, roundStatus }: FinalizationTabProps) {project.currentState.replace('_', ' ')} + {hasDocColumn && ( + + = (project.documentsRequired ?? 0) + ? 'text-green-700' + : (project.documentsSubmitted ?? 0) > 0 + ? 'text-amber-600' + : 'text-muted-foreground', + )}> + {project.documentsSubmitted ?? 0}/{project.documentsRequired ?? 0} + + + )} {summary?.roundType === 'EVALUATION' && ( {project.evaluationScore != null @@ -555,6 +576,9 @@ export function FinalizationTab({ roundId, roundStatus }: FinalizationTabProps) Category Country Current State + {hasDocColumn && ( + Docs + )} {summary.roundType === 'EVALUATION' && ( Score / Rank )} diff --git a/src/server/services/round-finalization.ts b/src/server/services/round-finalization.ts index 447c1d9..f08406f 100644 --- a/src/server/services/round-finalization.ts +++ b/src/server/services/round-finalization.ts @@ -44,6 +44,8 @@ export type FinalizationSummary = { proposedOutcome: ProjectRoundStateValue | null evaluationScore?: number | null rankPosition?: number | null + documentsSubmitted?: number | null + documentsRequired?: number | null }> categoryTargets: { startupTarget: number | null @@ -487,6 +489,34 @@ export async function getFinalizationSummary( } } + // Get document submission counts for SUBMISSION/INTAKE rounds + let documentsRequired: number | null = null + let docCountMap = new Map() + + if (round.roundType === 'SUBMISSION' || round.roundType === 'INTAKE') { + const requirements = await prisma.fileRequirement.findMany({ + where: { roundId, isRequired: true }, + select: { id: true }, + }) + documentsRequired = requirements.length + + if (documentsRequired > 0) { + const projectIds = projectStates.map((prs: any) => prs.project.id) + const fileCounts = await prisma.projectFile.groupBy({ + by: ['projectId'], + where: { + roundId, + projectId: { in: projectIds }, + requirementId: { in: requirements.map((r) => r.id) }, + }, + _count: { _all: true }, + }) + for (const fc of fileCounts) { + docCountMap.set(fc.projectId, fc._count._all) + } + } + } + // Build project list const projects = projectStates.map((prs: any) => ({ id: prs.project.id, @@ -498,6 +528,8 @@ export async function getFinalizationSummary( proposedOutcome: prs.proposedOutcome as ProjectRoundStateValue | null, evaluationScore: scoreMap.get(prs.project.id) ?? null, rankPosition: rankMap.get(prs.project.id) ?? null, + documentsSubmitted: documentsRequired != null ? (docCountMap.get(prs.project.id) ?? 0) : null, + documentsRequired, })) // Category target progress