All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
The admin upload flow accepted roundId but never wrote it to the ProjectFile record, causing all admin-uploaded files to appear under "General". Fixed the create call, the listByProject filter, and the listByProjectForStage grouping to also use the direct roundId field. Jury assignments on the project detail page are now grouped by round with per-round completion counts instead of a flat list. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
127 lines
4.1 KiB
TypeScript
127 lines
4.1 KiB
TypeScript
'use client'
|
|
|
|
import { trpc } from '@/lib/trpc/client'
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
|
import { Skeleton } from '@/components/ui/skeleton'
|
|
import { FileText } from 'lucide-react'
|
|
import { FileViewer } from '@/components/shared/file-viewer'
|
|
|
|
interface MultiWindowDocViewerProps {
|
|
roundId: string
|
|
projectId: string
|
|
}
|
|
|
|
export function MultiWindowDocViewer({ roundId, projectId }: MultiWindowDocViewerProps) {
|
|
const { data: files, isLoading } = trpc.file.listByProject.useQuery(
|
|
{ projectId },
|
|
{ enabled: !!projectId }
|
|
)
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<Skeleton className="h-6 w-48" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Skeleton className="h-64" />
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
if (!files || files.length === 0) {
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Documents</CardTitle>
|
|
<CardDescription>Project files and submissions</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="text-center py-8">
|
|
<FileText className="h-12 w-12 text-muted-foreground/50 mx-auto mb-3" />
|
|
<p className="text-sm text-muted-foreground">No files uploaded</p>
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
// Group files by round name for the grouped view
|
|
const groupMap: Record<string, {
|
|
roundId: string | null
|
|
roundName: string
|
|
sortOrder: number
|
|
files: typeof files
|
|
}> = {}
|
|
|
|
for (const file of files) {
|
|
const rId = file.requirement?.round?.id ?? (file as any).roundId ?? null
|
|
const roundName = file.requirement?.round?.name ?? (rId ? 'Round Files' : 'General')
|
|
const sortOrder = file.requirement?.round?.sortOrder ?? 999
|
|
if (!groupMap[roundName]) {
|
|
groupMap[roundName] = { roundId: rId, roundName, sortOrder, files: [] }
|
|
}
|
|
groupMap[roundName].files.push(file)
|
|
}
|
|
|
|
const groupedFiles = Object.values(groupMap)
|
|
|
|
// If only one group, use flat view
|
|
if (groupedFiles.length === 1) {
|
|
const mappedFiles = files.map((f) => ({
|
|
id: f.id,
|
|
fileType: (f.fileType ?? 'OTHER') as 'EXEC_SUMMARY' | 'PRESENTATION' | 'VIDEO' | 'OTHER' | 'BUSINESS_PLAN' | 'VIDEO_PITCH' | 'SUPPORTING_DOC',
|
|
fileName: f.fileName,
|
|
mimeType: f.mimeType,
|
|
size: f.size,
|
|
bucket: f.bucket,
|
|
objectKey: f.objectKey,
|
|
version: f.version ?? undefined,
|
|
requirementId: f.requirementId,
|
|
requirement: f.requirement ? {
|
|
id: f.requirement.id,
|
|
name: f.requirement.name,
|
|
description: f.requirement.description,
|
|
isRequired: f.requirement.isRequired,
|
|
} : undefined,
|
|
pageCount: (f as any).pageCount ?? undefined,
|
|
textPreview: (f as any).textPreview ?? undefined,
|
|
detectedLang: (f as any).detectedLang ?? undefined,
|
|
langConfidence: (f as any).langConfidence ?? undefined,
|
|
analyzedAt: (f as any).analyzedAt ?? undefined,
|
|
}))
|
|
|
|
return <FileViewer files={mappedFiles} />
|
|
}
|
|
|
|
// Multiple groups — use grouped view
|
|
const mappedGroups = groupedFiles.map((g) => ({
|
|
roundId: g.roundId,
|
|
roundName: g.roundName,
|
|
sortOrder: g.sortOrder,
|
|
files: g.files.map((f) => ({
|
|
id: f.id,
|
|
fileType: (f.fileType ?? 'OTHER') as 'EXEC_SUMMARY' | 'PRESENTATION' | 'VIDEO' | 'OTHER' | 'BUSINESS_PLAN' | 'VIDEO_PITCH' | 'SUPPORTING_DOC',
|
|
fileName: f.fileName,
|
|
mimeType: f.mimeType,
|
|
size: f.size,
|
|
bucket: f.bucket,
|
|
objectKey: f.objectKey,
|
|
version: f.version ?? undefined,
|
|
requirementId: f.requirementId,
|
|
requirement: f.requirement ? {
|
|
id: f.requirement.id,
|
|
name: f.requirement.name,
|
|
description: f.requirement.description,
|
|
isRequired: f.requirement.isRequired,
|
|
} : undefined,
|
|
pageCount: (f as any).pageCount ?? undefined,
|
|
textPreview: (f as any).textPreview ?? undefined,
|
|
detectedLang: (f as any).detectedLang ?? undefined,
|
|
langConfidence: (f as any).langConfidence ?? undefined,
|
|
analyzedAt: (f as any).analyzedAt ?? undefined,
|
|
})),
|
|
}))
|
|
|
|
return <FileViewer groupedFiles={mappedGroups} />
|
|
}
|