'use client' import { useState, useCallback, useEffect, useMemo } from 'react' import { trpc } from '@/lib/trpc/client' import { toast } from 'sonner' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { Badge } from '@/components/ui/badge' import { Label } from '@/components/ui/label' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table' import { ArrowRightCircle, Loader2, Info } from 'lucide-react' interface AdvanceProjectsDialogProps { roundId: string programId: string open: boolean onOpenChange: (open: boolean) => void onSuccess?: () => void } export function AdvanceProjectsDialog({ roundId, programId, open, onOpenChange, onSuccess, }: AdvanceProjectsDialogProps) { const [selectedIds, setSelectedIds] = useState>(new Set()) const [targetRoundId, setTargetRoundId] = useState('') const utils = trpc.useUtils() // Reset state when dialog opens useEffect(() => { if (open) { setSelectedIds(new Set()) setTargetRoundId('') } }, [open]) // Fetch rounds in program const { data: roundsData } = trpc.round.list.useQuery( { programId }, { enabled: open } ) // Fetch projects in current round const { data: projectsData, isLoading } = trpc.project.list.useQuery( { roundId, page: 1, perPage: 5000 }, { enabled: open } ) // Auto-select next round by sortOrder const otherRounds = useMemo(() => { if (!roundsData) return [] return roundsData .filter((r) => r.id !== roundId) .sort((a, b) => a.sortOrder - b.sortOrder) }, [roundsData, roundId]) const currentRound = useMemo(() => { return roundsData?.find((r) => r.id === roundId) }, [roundsData, roundId]) // Auto-select next round in sort order useEffect(() => { if (open && otherRounds.length > 0 && !targetRoundId && currentRound) { const nextRound = otherRounds.find( (r) => r.sortOrder > currentRound.sortOrder ) setTargetRoundId(nextRound?.id || otherRounds[0].id) } }, [open, otherRounds, targetRoundId, currentRound]) const advanceMutation = trpc.round.advanceProjects.useMutation({ onSuccess: (result) => { const targetName = otherRounds.find((r) => r.id === targetRoundId)?.name toast.success( `${result.advanced} project${result.advanced !== 1 ? 's' : ''} advanced to ${targetName}` ) utils.round.get.invalidate() utils.project.list.invalidate() onSuccess?.() onOpenChange(false) }, onError: (error) => { toast.error(error.message) }, }) const projects = projectsData?.projects ?? [] const toggleProject = useCallback((id: string) => { setSelectedIds((prev) => { const next = new Set(prev) if (next.has(id)) next.delete(id) else next.add(id) return next }) }, []) const toggleAll = useCallback(() => { if (selectedIds.size === projects.length) { setSelectedIds(new Set()) } else { setSelectedIds(new Set(projects.map((p) => p.id))) } }, [selectedIds.size, projects]) const handleAdvance = () => { if (selectedIds.size === 0 || !targetRoundId) return advanceMutation.mutate({ fromRoundId: roundId, toRoundId: targetRoundId, projectIds: Array.from(selectedIds), }) } const targetRoundName = otherRounds.find((r) => r.id === targetRoundId)?.name return ( Advance Projects Select projects to advance to the next round. Projects will remain visible in the current round.
{otherRounds.length === 0 ? (

No other rounds available in this program. Create another round first.

) : ( )}
Projects will be copied to the target round with "Submitted" status. They will remain in the current round with their existing status.
{isLoading ? (
) : projects.length === 0 ? (

No projects in this round

Assign projects to this round first.

) : (
0} onCheckedChange={toggleAll} /> {selectedIds.size} of {projects.length} selected
Project Team Status {projects.map((project) => ( toggleProject(project.id)} > toggleProject(project.id)} onClick={(e) => e.stopPropagation()} /> {project.title} {project.teamName || '—'} {(project.roundProjects?.[0]?.status ?? 'SUBMITTED').replace('_', ' ')} ))}
)}
) }