'use client' import { Suspense, use } from 'react' import Link from 'next/link' import type { Route } from 'next' import { trpc } from '@/lib/trpc/client' import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Skeleton } from '@/components/ui/skeleton' import { Separator } from '@/components/ui/separator' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table' import { FileViewer } from '@/components/shared/file-viewer' import { FileUpload } from '@/components/shared/file-upload' import { ProjectLogoWithUrl } from '@/components/shared/project-logo-with-url' import { Avatar, AvatarFallback } from '@/components/ui/avatar' import { ArrowLeft, Edit, AlertCircle, Users, FileText, Calendar, CheckCircle2, XCircle, Clock, BarChart3, ThumbsUp, ThumbsDown, MapPin, Waves, GraduationCap, Heart, Crown, UserPlus, } from 'lucide-react' import { formatDate, formatDateOnly, getInitials } from '@/lib/utils' interface PageProps { params: Promise<{ id: string }> } // Status badge colors const statusColors: Record = { SUBMITTED: 'secondary', ELIGIBLE: 'default', ASSIGNED: 'default', SEMIFINALIST: 'default', FINALIST: 'default', REJECTED: 'destructive', } // Evaluation status colors const evalStatusColors: Record = { NOT_STARTED: 'outline', DRAFT: 'secondary', SUBMITTED: 'default', LOCKED: 'default', } function ProjectDetailContent({ projectId }: { projectId: string }) { // Fetch project data const { data: project, isLoading } = trpc.project.get.useQuery({ id: projectId, }) // Fetch files const { data: files } = trpc.file.listByProject.useQuery({ projectId }) // Fetch assignments const { data: assignments } = trpc.assignment.listByProject.useQuery({ projectId, }) // Fetch evaluation stats const { data: stats } = trpc.evaluation.getProjectStats.useQuery({ projectId, }) const utils = trpc.useUtils() if (isLoading) { return } if (!project) { return (

Project Not Found

) } return (
{/* Header */}
{project.round.name}

{project.title}

{project.status.replace('_', ' ')}
{project.teamName && (

{project.teamName}

)}
{/* Stats Grid */} {stats && (
Average Score
{stats.averageGlobalScore?.toFixed(1) || '-'}

Range: {stats.minScore || '-'} - {stats.maxScore || '-'}

Recommendations
{stats.yesPercentage?.toFixed(0) || 0}%

{stats.yesVotes} yes / {stats.noVotes} no

)} {/* Project Info */} Project Information {/* Category & Ocean Issue badges */}
{project.competitionCategory && ( {project.competitionCategory === 'STARTUP' ? 'Start-up' : 'Business Concept'} )} {project.oceanIssue && ( {project.oceanIssue.replace(/_/g, ' ')} )} {project.wantsMentorship && ( Wants Mentorship )}
{project.description && (

Description

{project.description}

)} {/* Location & Institution */}
{(project.country || project.geographicZone) && (

Location

{project.geographicZone || project.country}

)} {project.institution && (

Institution

{project.institution}

)}
{/* Submission URLs */} {(project.phase1SubmissionUrl || project.phase2SubmissionUrl) && (

Submission Links

{project.phase1SubmissionUrl && ( )} {project.phase2SubmissionUrl && ( )}
)} {project.tags && project.tags.length > 0 && (

Tags

{project.tags.map((tag) => ( {tag} ))}
)} {/* Internal Info */} {(project.internalComments || project.applicationStatus || project.referralSource) && (

Internal Notes

{project.applicationStatus && (

Application Status

{project.applicationStatus}

)} {project.referralSource && (

Referral Source

{project.referralSource}

)}
{project.internalComments && (

Comments

{project.internalComments}

)}
)}
Created:{' '} {formatDateOnly(project.createdAt)}
Updated:{' '} {formatDateOnly(project.updatedAt)}
{/* Team Members Section */} {project.teamMembers && project.teamMembers.length > 0 && (
Team Members ({project.teamMembers.length})
{project.teamMembers.map((member: { id: string; role: string; title: string | null; user: { id: string; name: string | null; email: string } }) => (
{member.role === 'LEAD' ? ( ) : ( {getInitials(member.user.name || member.user.email)} )}

{member.user.name || 'Unnamed'}

{member.role === 'LEAD' ? 'Lead' : member.role === 'ADVISOR' ? 'Advisor' : 'Member'}

{member.user.email}

{member.title && (

{member.title}

)}
))}
)} {/* Mentor Assignment Section */} {project.wantsMentorship && (
Mentor Assignment {!project.mentorAssignment && ( )}
{project.mentorAssignment ? (
{getInitials(project.mentorAssignment.mentor.name || project.mentorAssignment.mentor.email)}

{project.mentorAssignment.mentor.name || 'Unnamed'}

{project.mentorAssignment.mentor.email}

{project.mentorAssignment.method.replace('_', ' ')}
) : (

No mentor assigned yet. The applicant has requested mentorship support.

)}
)} {/* Files Section */} Files Project documents and materials {files && files.length > 0 ? ( ({ id: f.id, fileName: f.fileName, fileType: f.fileType, mimeType: f.mimeType, size: f.size, bucket: f.bucket, objectKey: f.objectKey, }))} /> ) : (

No files uploaded yet

)}

Upload New Files

{ utils.file.listByProject.invalidate({ projectId }) }} />
{/* Assignments Section */} {assignments && assignments.length > 0 && (
Jury Assignments {assignments.filter((a) => a.evaluation?.status === 'SUBMITTED') .length}{' '} of {assignments.length} evaluations completed
Juror Expertise Status Score Decision {assignments.map((assignment) => (
{getInitials(assignment.user.name || assignment.user.email)}

{assignment.user.name || 'Unnamed'}

{assignment.user.email}

{assignment.user.expertiseTags?.slice(0, 2).map((tag) => ( {tag} ))} {(assignment.user.expertiseTags?.length || 0) > 2 && ( +{(assignment.user.expertiseTags?.length || 0) - 2} )}
{(assignment.evaluation?.status || 'NOT_STARTED').replace( '_', ' ' )} {assignment.evaluation?.globalScore !== null && assignment.evaluation?.globalScore !== undefined ? ( {assignment.evaluation.globalScore}/10 ) : ( - )} {assignment.evaluation?.binaryDecision !== null && assignment.evaluation?.binaryDecision !== undefined ? ( assignment.evaluation.binaryDecision ? (
Yes
) : (
No
) ) : ( - )}
))}
)}
) } function ProjectDetailSkeleton() { return (
{[1, 2, 3, 4].map((i) => ( ))}
) } export default function ProjectDetailPage({ params }: PageProps) { const { id } = use(params) return ( }> ) }