'use client' import { useState, useMemo } from 'react' import { useDebounce } from '@/hooks/use-debounce' import Link from 'next/link' 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 { Input } from '@/components/ui/input' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Plus, Trophy, Users, CheckCircle2, Search } from 'lucide-react' const STATUS_COLORS: Record = { DRAFT: 'secondary', NOMINATIONS_OPEN: 'default', VOTING_OPEN: 'default', CLOSED: 'outline', ARCHIVED: 'secondary', } const SCORING_LABELS: Record = { PICK_WINNER: 'Pick Winner', RANKED: 'Ranked', SCORED: 'Scored', } export default function AwardsListPage() { const { data: awards, isLoading } = trpc.specialAward.list.useQuery({}) const [search, setSearch] = useState('') const debouncedSearch = useDebounce(search, 300) const [statusFilter, setStatusFilter] = useState('all') const [scoringFilter, setScoringFilter] = useState('all') const filteredAwards = useMemo(() => { if (!awards) return [] return awards.filter((award) => { const matchesSearch = !debouncedSearch || award.name.toLowerCase().includes(debouncedSearch.toLowerCase()) || award.description?.toLowerCase().includes(debouncedSearch.toLowerCase()) const matchesStatus = statusFilter === 'all' || award.status === statusFilter const matchesScoring = scoringFilter === 'all' || award.scoringMode === scoringFilter return matchesSearch && matchesStatus && matchesScoring }) }, [awards, debouncedSearch, statusFilter, scoringFilter]) if (isLoading) { return (
{/* Toolbar skeleton */}
{/* Cards skeleton */}
{[...Array(6)].map((_, i) => ( ))}
) } return (
{/* Header */}

Special Awards

Manage named awards with eligibility criteria and jury voting

{/* Toolbar */}
setSearch(e.target.value)} className="pl-9" />
{/* Results count */} {awards && (

{filteredAwards.length} of {awards.length} awards

)} {/* Awards Grid */} {filteredAwards.length > 0 ? (
{filteredAwards.map((award) => (
{award.name} {award.status.replace('_', ' ')}
{award.description && ( {award.description} )}
{award._count.eligibilities} eligible
{award._count.jurors} jurors
{SCORING_LABELS[award.scoringMode] || award.scoringMode}
{award.winnerProject && (

Winner:{' '} {award.winnerProject.title}

)}
))}
) : awards && awards.length > 0 ? (

No awards match your filters

) : (

No awards yet

Create special awards with eligibility criteria and jury voting for outstanding projects.

)}
) }