diff --git a/src/app/(admin)/admin/rounds/[roundId]/page.tsx b/src/app/(admin)/admin/rounds/[roundId]/page.tsx index 64b2153..b101cc8 100644 --- a/src/app/(admin)/admin/rounds/[roundId]/page.tsx +++ b/src/app/(admin)/admin/rounds/[roundId]/page.tsx @@ -71,7 +71,6 @@ import { FileText, Trophy, Clock, - Upload, Send, Download, Plus, @@ -99,13 +98,14 @@ import { import { ScrollArea } from '@/components/ui/scroll-area' import { RoundConfigForm } from '@/components/admin/competition/round-config-form' import { ProjectStatesTable } from '@/components/admin/round/project-states-table' -import { SubmissionWindowManager } from '@/components/admin/round/submission-window-manager' +// SubmissionWindowManager removed — round dates + file requirements in Config are sufficient import { FileRequirementsEditor } from '@/components/admin/round/file-requirements-editor' import { FilteringDashboard } from '@/components/admin/round/filtering-dashboard' import { CoverageReport } from '@/components/admin/assignment/coverage-report' import { AssignmentPreviewSheet } from '@/components/admin/assignment/assignment-preview-sheet' import { CsvExportDialog } from '@/components/shared/csv-export-dialog' import { AnimatedCard } from '@/components/shared/animated-container' +import { DateTimePicker } from '@/components/ui/datetime-picker' import { AddMemberDialog } from '@/components/admin/jury/add-member-dialog' import { motion } from 'motion/react' @@ -178,6 +178,7 @@ export default function RoundDetailPage() { const [createJuryOpen, setCreateJuryOpen] = useState(false) const [newJuryName, setNewJuryName] = useState('') const [addMemberOpen, setAddMemberOpen] = useState(false) + const [closeAndAdvance, setCloseAndAdvance] = useState(false) const utils = trpc.useUtils() @@ -244,8 +245,16 @@ export default function RoundDetailPage() { onSuccess: () => { utils.round.getById.invalidate({ id: roundId }) toast.success('Round closed') + if (closeAndAdvance) { + setCloseAndAdvance(false) + // Small delay to let cache invalidation complete before opening dialog + setTimeout(() => setAdvanceDialogOpen(true), 300) + } + }, + onError: (err) => { + setCloseAndAdvance(false) + toast.error(err.message) }, - onError: (err) => toast.error(err.message), }) const reopenMutation = trpc.roundEngine.reopen.useMutation({ @@ -367,6 +376,8 @@ export default function RoundDetailPage() { const isFiltering = round?.roundType === 'FILTERING' const isEvaluation = round?.roundType === 'EVALUATION' + const hasJury = ['EVALUATION', 'LIVE_FINAL', 'DELIBERATION'].includes(round?.roundType ?? '') + const hasAwards = hasJury const poolLink = `/admin/projects/pool?roundId=${roundId}&competitionId=${competitionId}` as Route @@ -424,7 +435,7 @@ export default function RoundDetailPage() { action: projectCount === 0 ? poolLink : undefined, actionLabel: 'Assign Projects', }, - ...((isEvaluation || isFiltering) + ...(hasJury ? [{ label: 'Jury group set', ready: !!juryGroup, @@ -712,10 +723,9 @@ export default function RoundDetailPage() { { value: 'projects', label: 'Projects', icon: Layers }, ...(isFiltering ? [{ value: 'filtering', label: 'Filtering', icon: Shield }] : []), ...(isEvaluation ? [{ value: 'assignments', label: 'Assignments', icon: ClipboardList }] : []), - { value: 'jury', label: 'Jury', icon: Users }, + ...(hasJury ? [{ value: 'jury', label: 'Jury', icon: Users }] : []), { value: 'config', label: 'Config', icon: Settings }, - { value: 'windows', label: 'Document Windows', icon: Upload }, - { value: 'awards', label: 'Awards', icon: Trophy }, + ...(hasAwards ? [{ value: 'awards', label: 'Awards', icon: Trophy }] : []), ].map((tab) => ( - {/* Advance projects (shown when PASSED > 0) */} - {passedCount > 0 && ( + {/* Advance projects (always visible when projects exist) */} + {projectCount > 0 && ( )} - {/* Jury assignment for evaluation/filtering */} - {(isEvaluation || isFiltering) && !juryGroup && ( + {/* Close & Advance (active rounds with passed projects) */} + {status === 'ROUND_ACTIVE' && passedCount > 0 && ( + + )} + + {/* Jury assignment for rounds that use jury */} + {hasJury && !juryGroup && (