'use client'
import { Suspense } from 'react'
import Link from 'next/link'
import { trpc } from '@/lib/trpc/client'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import {
Plus,
MoreHorizontal,
Eye,
Edit,
Users,
FileText,
Calendar,
CheckCircle2,
Clock,
Archive,
} from 'lucide-react'
import { format, isPast, isFuture } from 'date-fns'
function RoundsContent() {
const { data: programs, isLoading } = trpc.program.list.useQuery({
includeRounds: true,
})
if (isLoading) {
return
}
if (!programs || programs.length === 0) {
return (
No Programs Found
Create a program first to start managing rounds
)
}
return (
{programs.map((program) => (
{program.name}
{program.year} - {program.status}
{program.rounds && program.rounds.length > 0 ? (
Round
Status
Voting Window
Projects
Assignments
Actions
{program.rounds.map((round) => (
))}
) : (
)}
))}
)
}
function RoundRow({ round }: { round: any }) {
const utils = trpc.useUtils()
const updateStatus = trpc.round.updateStatus.useMutation({
onSuccess: () => {
utils.program.list.invalidate()
},
})
const getStatusBadge = () => {
const now = new Date()
const isVotingOpen =
round.status === 'ACTIVE' &&
round.votingStartAt &&
round.votingEndAt &&
new Date(round.votingStartAt) <= now &&
new Date(round.votingEndAt) >= now
if (round.status === 'ACTIVE' && isVotingOpen) {
return (
Voting Open
)
}
switch (round.status) {
case 'DRAFT':
return Draft
case 'ACTIVE':
return (
Active
)
case 'CLOSED':
return Closed
case 'ARCHIVED':
return (
Archived
)
default:
return {round.status}
}
}
const getVotingWindow = () => {
if (!round.votingStartAt || !round.votingEndAt) {
return Not set
}
const start = new Date(round.votingStartAt)
const end = new Date(round.votingEndAt)
const now = new Date()
if (isFuture(start)) {
return (
Opens {format(start, 'MMM d, yyyy')}
)
}
if (isPast(end)) {
return (
Ended {format(end, 'MMM d, yyyy')}
)
}
return (
Until {format(end, 'MMM d, yyyy')}
)
}
return (
{round.name}
{getStatusBadge()}
{getVotingWindow()}
{round._count?.projects || 0}
{round._count?.assignments || 0}
View Details
Edit Round
Manage Assignments
{round.status === 'DRAFT' && (
updateStatus.mutate({ id: round.id, status: 'ACTIVE' })
}
>
Activate Round
)}
{round.status === 'ACTIVE' && (
updateStatus.mutate({ id: round.id, status: 'CLOSED' })
}
>
Close Round
)}
{round.status === 'CLOSED' && (
updateStatus.mutate({ id: round.id, status: 'ARCHIVED' })
}
>
Archive Round
)}
)
}
function RoundsListSkeleton() {
return (
{[1, 2].map((i) => (
{[1, 2, 3].map((j) => (
))}
))}
)
}
export default function RoundsPage() {
return (
{/* Header */}
Rounds
Manage selection rounds and voting periods
{/* Content */}
}>
)
}