'use client' import Link from 'next/link' import { Badge } from '@/components/ui/badge' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip' import { Filter, ClipboardCheck, Zap, CheckCircle2, Clock, Archive, ChevronRight, FileText, Users, AlertTriangle, } from 'lucide-react' import { cn } from '@/lib/utils' type PipelineRound = { id: string name: string status: string roundType: string _count?: { projects: number assignments: number } } interface RoundPipelineProps { rounds: PipelineRound[] programName?: string } const typeIcons: Record = { FILTERING: Filter, EVALUATION: ClipboardCheck, LIVE_EVENT: Zap, } const typeColors: Record = { FILTERING: { bg: 'bg-amber-50 dark:bg-amber-950/30', text: 'text-amber-700 dark:text-amber-300', border: 'border-amber-200 dark:border-amber-800', }, EVALUATION: { bg: 'bg-blue-50 dark:bg-blue-950/30', text: 'text-blue-700 dark:text-blue-300', border: 'border-blue-200 dark:border-blue-800', }, LIVE_EVENT: { bg: 'bg-violet-50 dark:bg-violet-950/30', text: 'text-violet-700 dark:text-violet-300', border: 'border-violet-200 dark:border-violet-800', }, } const statusConfig: Record = { DRAFT: { color: 'text-muted-foreground', icon: Clock, label: 'Draft' }, ACTIVE: { color: 'text-green-600', icon: CheckCircle2, label: 'Active' }, CLOSED: { color: 'text-amber-600', icon: Archive, label: 'Closed' }, ARCHIVED: { color: 'text-muted-foreground', icon: Archive, label: 'Archived' }, } export function RoundPipeline({ rounds }: RoundPipelineProps) { if (rounds.length === 0) return null // Detect bottlenecks: rounds with many more incoming projects than outgoing const projectCounts = rounds.map((r) => r._count?.projects || 0) return (
{rounds.map((round, index) => { const TypeIcon = typeIcons[round.roundType] || ClipboardCheck const colors = typeColors[round.roundType] || typeColors.EVALUATION const status = statusConfig[round.status] || statusConfig.DRAFT const StatusIcon = status.icon const projectCount = round._count?.projects || 0 const prevCount = index > 0 ? projectCounts[index - 1] : 0 const dropRate = prevCount > 0 ? Math.round(((prevCount - projectCount) / prevCount) * 100) : 0 const isBottleneck = dropRate > 50 && index > 0 return (
{/* Round Card */} {/* Status indicator dot */}
{/* Type Icon */}
{/* Round Name */}

{round.name}

{/* Stats Row */}
{projectCount} {round._count?.assignments !== undefined && round._count.assignments > 0 && ( {round._count.assignments} )}
{/* Status Badge */} {status.label} {/* Bottleneck indicator */} {isBottleneck && (
)}

{round.name}

{round.roundType.toLowerCase().replace('_', ' ')} · {round.status.toLowerCase()}

{projectCount} projects {round._count?.assignments ? `, ${round._count.assignments} assignments` : ''}

{isBottleneck && (

{dropRate}% drop from previous round

)}
{/* Arrow connector */} {index < rounds.length - 1 && (
{prevCount > 0 && index > 0 && dropRate > 0 && ( -{dropRate}% )} {index === 0 && projectCounts[0] > 0 && projectCounts[1] !== undefined && ( {projectCounts[0]} → {projectCounts[1] || '?'} )}
)}
) })}
) }