'use client' import { useState } from 'react' import Link from 'next/link' import type { Route } from 'next' import { trpc } from '@/lib/trpc/client' import { useEdition } from '@/contexts/edition-context' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Card, CardContent, CardHeader, CardTitle, CardDescription, } from '@/components/ui/card' import { Skeleton } from '@/components/ui/skeleton' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Textarea } from '@/components/ui/textarea' import { toast } from 'sonner' import { cn, formatEnumLabel } from '@/lib/utils' import { Plus, Scale, Users, Loader2, ArrowRight, CircleDot } from 'lucide-react' const capModeLabels = { HARD: 'Hard Cap', SOFT: 'Soft Cap', NONE: 'No Cap', } const capModeColors = { HARD: 'bg-red-100 text-red-700', SOFT: 'bg-amber-100 text-amber-700', NONE: 'bg-gray-100 text-gray-600', } export default function JuriesPage() { const { currentEdition } = useEdition() const programId = currentEdition?.id const utils = trpc.useUtils() const [createDialogOpen, setCreateDialogOpen] = useState(false) const [formData, setFormData] = useState({ competitionId: '', name: '', description: '', }) const { data: competitions, isLoading: loadingCompetitions } = trpc.competition.list.useQuery( { programId: programId! }, { enabled: !!programId } ) const createMutation = trpc.juryGroup.create.useMutation({ onSuccess: () => { utils.juryGroup.list.invalidate() toast.success('Jury group created') setCreateDialogOpen(false) setFormData({ competitionId: '', name: '', description: '' }) }, onError: (err) => toast.error(err.message), }) const handleCreate = () => { if (!formData.competitionId || !formData.name.trim()) { toast.error('Competition and name are required') return } const slug = formData.name .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-|-$/g, '') createMutation.mutate({ competitionId: formData.competitionId, name: formData.name.trim(), slug, description: formData.description || undefined, }) } if (!programId) { return (

Juries

No Edition Selected

Select an edition from the sidebar

) } return (
{/* Header */}

Juries

Manage jury groups for {currentEdition?.name}

{/* Loading */} {loadingCompetitions && (
{[1, 2].map((i) => ( ))}
)} {/* Empty State */} {!loadingCompetitions && (!competitions || competitions.length === 0) && (

No Competitions Yet

Create a competition first, then add jury groups.

)} {/* Competition Groups */} {competitions && competitions.length > 0 && (
{competitions.map((comp) => ( ))}
)} {/* Create Dialog */} Create Jury Group Create a new jury panel for a competition.
setFormData({ ...formData, name: e.target.value })} />