'use client' import { useState } from 'react' import { trpc } from '@/lib/trpc/client' import { toast } from 'sonner' import { cn } from '@/lib/utils' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Skeleton } from '@/components/ui/skeleton' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip' import { Loader2, Mail, ArrowRightLeft, UserPlus } from 'lucide-react' import { TransferAssignmentsDialog } from './transfer-assignments-dialog' export type JuryProgressTableProps = { roundId: string } export function JuryProgressTable({ roundId }: JuryProgressTableProps) { const utils = trpc.useUtils() const [transferJuror, setTransferJuror] = useState<{ id: string; name: string } | null>(null) const { data: workload, isLoading } = trpc.analytics.getJurorWorkload.useQuery( { roundId }, { refetchInterval: 15_000 }, ) const notifyMutation = trpc.assignment.notifySingleJurorOfAssignments.useMutation({ onSuccess: (data) => { toast.success(`Notified juror of ${data.projectCount} assignment(s)`) }, onError: (err) => toast.error(err.message), }) const reshuffleMutation = trpc.assignment.reassignDroppedJuror.useMutation({ onSuccess: (data) => { utils.assignment.listByStage.invalidate({ roundId }) utils.roundEngine.getProjectStates.invalidate({ roundId }) utils.analytics.getJurorWorkload.invalidate({ roundId }) utils.roundAssignment.unassignedQueue.invalidate({ roundId }) if (data.failedCount > 0) { toast.warning(`Dropped juror and reassigned ${data.movedCount} project(s). ${data.failedCount} could not be reassigned (all remaining jurors at cap/blocked).`) } else { toast.success(`Dropped juror and reassigned ${data.movedCount} project(s) evenly across available jurors.`) } }, onError: (err) => toast.error(err.message), }) return ( <> Jury Progress Evaluation completion per juror. Click the mail icon to notify an individual juror. {isLoading ? (
{[1, 2, 3].map((i) => )}
) : !workload || workload.length === 0 ? (

No assignments yet

) : (
{workload.map((juror) => { const pct = juror.completionRate const barGradient = pct === 100 ? 'bg-gradient-to-r from-emerald-400 to-emerald-600' : pct >= 50 ? 'bg-gradient-to-r from-blue-400 to-blue-600' : pct > 0 ? 'bg-gradient-to-r from-amber-400 to-amber-600' : 'bg-gray-300' return (
{juror.name}
{juror.completed}/{juror.assigned} ({pct}%)

Notify this juror of their assignments

Transfer assignments to other jurors

Drop juror + reshuffle pending projects

) })}
)} {transferJuror && ( setTransferJuror(null)} /> )} ) }