'use client' import { use, useRef, useState } from 'react' import { useRouter } from 'next/navigation' import type { Route } from 'next' import { trpc } from '@/lib/trpc/client' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Skeleton } from '@/components/ui/skeleton' import { Textarea } from '@/components/ui/textarea' import { Separator } from '@/components/ui/separator' import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog' import { toast } from 'sonner' import { ArrowLeft, Trophy, CheckCircle2, Loader2, ChevronDown, ChevronUp, FileText, Star, Users, } from 'lucide-react' import { cn } from '@/lib/utils' import { CountryDisplay } from '@/components/shared/country-display' import { ProjectFilesSection } from '@/components/jury/project-files-section' export default function AwardMasterVotingPage({ params, }: { params: Promise<{ id: string }> }) { const { id: awardId } = use(params) const router = useRouter() // State const [selectedProjectId, setSelectedProjectId] = useState( null ) const [expandedProjectId, setExpandedProjectId] = useState( null ) const [justification, setJustification] = useState('') // Queries & mutations const utils = trpc.useUtils() const { data, isLoading } = trpc.specialAward.getMyAwardDetailEnhanced.useQuery({ awardId }) const submitVote = trpc.specialAward.submitAwardMasterVote.useMutation({ onSuccess: () => { utils.specialAward.getMyAwardDetailEnhanced.invalidate({ awardId }) toast.success('Vote submitted') }, onError: (err) => toast.error(err.message), }) const confirmWinner = trpc.specialAward.confirmWinner.useMutation({ onSuccess: () => { utils.specialAward.getMyAwardDetailEnhanced.invalidate({ awardId }) toast.success('Winner confirmed and award closed') }, onError: (err) => toast.error(err.message), }) // Initialize selection from existing vote const initializedRef = useRef(false) if (data && !initializedRef.current && data.myVotes.length > 0) { initializedRef.current = true setSelectedProjectId(data.myVotes[0].projectId) if (data.myVotes[0].justification) { setJustification(data.myVotes[0].justification) } } // Loading state if (isLoading) { return (
{[...Array(6)].map((_, i) => ( ))}
) } if (!data) return null // Destructure data const { award, projects, myVotes, isChair, otherVotes, totalJurors } = data const hasVoted = myVotes.length > 0 const isVotingOpen = award.status === 'VOTING_OPEN' const isClosed = award.status === 'CLOSED' const selectedProject = projects.find((p) => p.id === selectedProjectId) // Toggle project expansion const handleProjectClick = (projectId: string) => { if (isVotingOpen) setSelectedProjectId(projectId) setExpandedProjectId(expandedProjectId === projectId ? null : projectId) } // Submit vote handler const handleSubmitVote = () => { if (!selectedProjectId) return submitVote.mutate({ awardId, projectId: selectedProjectId, justification: justification.trim() || undefined, }) } // Confirm winner handler const handleConfirmWinner = () => { confirmWinner.mutate({ awardId }) } // Find the winner project for closed state const winnerProject = isClosed ? projects.find((p) => p.id === award.winnerProjectId) : null return (
{/* Back button */}
{/* Header */}

{award.name}

{award.status.replace('_', ' ')} {hasVoted && !isClosed && ( Voted )} {award.competition && ( {award.competition.name} )}
{award.criteriaText && (

Criteria: {award.criteriaText}

)}
{/* Closed State */} {isClosed ? (

Award Finalized

{winnerProject ? (

{winnerProject.title}

{winnerProject.teamName && (

{winnerProject.teamName}

)}
) : (

This award has been finalized

)}
) : ( <> {/* Project Grid */}

Eligible Projects ({projects.length})

{isVotingOpen && (

Click a project to select it as your pick and expand details

)}
{projects.map((project) => (
handleProjectClick(project.id)} >
{project.title} {project.teamName && ( {project.teamName} )}
{expandedProjectId === project.id ? ( ) : ( )}
{project.competitionCategory && ( {project.competitionCategory.replace(/_/g, ' ')} )} {project.country && ( )} {project.evaluationScore && ( Avg: {project.evaluationScore.avg.toFixed(1)}/10 ( {project.evaluationScore.count}{' '} {project.evaluationScore.count === 1 ? 'review' : 'reviews'} ) )} {selectedProjectId === project.id && ( Selected )}
{/* Expanded Project Detail */} {expandedProjectId === project.id && ( {project.description && (

Description

{project.description}

)} {award.evaluationRoundId && (

Documents

)} {project.evaluationScore && (

Evaluation Score

{project.evaluationScore.avg.toFixed(1)} / 10

Based on {project.evaluationScore.count}{' '} {project.evaluationScore.count === 1 ? 'evaluation' : 'evaluations'}

)}
)}
))}
{/* Vote Section */} {isVotingOpen && ( Your Vote {hasVoted ? 'You can update your vote until the award is finalized' : 'Select a project above and submit your vote'} {selectedProject ? (

Your selection

{selectedProject.title}

{selectedProject.teamName && (

{selectedProject.teamName}

)}
) : (

No project selected. Click a project card above to select it.

)}