diff --git a/src/app/(admin)/admin/awards/[id]/edit/page.tsx b/src/app/(admin)/admin/awards/[id]/edit/page.tsx
index 0bfc5b7..079644a 100644
--- a/src/app/(admin)/admin/awards/[id]/edit/page.tsx
+++ b/src/app/(admin)/admin/awards/[id]/edit/page.tsx
@@ -44,6 +44,16 @@ export default function EditAwardPage({
const [scoringMode, setScoringMode] = useState<'PICK_WINNER' | 'RANKED' | 'SCORED'>('PICK_WINNER')
const [useAiEligibility, setUseAiEligibility] = useState(true)
const [maxRankedPicks, setMaxRankedPicks] = useState('3')
+ const [votingStartAt, setVotingStartAt] = useState('')
+ const [votingEndAt, setVotingEndAt] = useState('')
+
+ // Helper to format date for datetime-local input
+ const formatDateForInput = (date: Date | string | null | undefined): string => {
+ if (!date) return ''
+ const d = new Date(date)
+ // Format: YYYY-MM-DDTHH:mm
+ return d.toISOString().slice(0, 16)
+ }
// Load existing values when award data arrives
useEffect(() => {
@@ -54,6 +64,8 @@ export default function EditAwardPage({
setScoringMode(award.scoringMode as 'PICK_WINNER' | 'RANKED' | 'SCORED')
setUseAiEligibility(award.useAiEligibility)
setMaxRankedPicks(String(award.maxRankedPicks || 3))
+ setVotingStartAt(formatDateForInput(award.votingStartAt))
+ setVotingEndAt(formatDateForInput(award.votingEndAt))
}
}, [award])
@@ -68,6 +80,8 @@ export default function EditAwardPage({
useAiEligibility,
scoringMode,
maxRankedPicks: scoringMode === 'RANKED' ? parseInt(maxRankedPicks) : undefined,
+ votingStartAt: votingStartAt ? new Date(votingStartAt) : undefined,
+ votingEndAt: votingEndAt ? new Date(votingEndAt) : undefined,
})
toast.success('Award updated')
router.push(`/admin/awards/${awardId}`)
@@ -211,6 +225,45 @@ export default function EditAwardPage({
+ {/* Voting Window Card */}
+
+ When jurors can start voting (leave empty to set when opening voting)
+
+ Deadline for juror votes
+
{e.project.title}
@@ -352,6 +567,11 @@ export default function AwardDetailPage({ )}No eligibility data
- Run AI eligibility to evaluate projects against criteria + Run AI eligibility to evaluate projects or manually add projects
diff --git a/src/app/(admin)/admin/rounds/[id]/assignments/page.tsx b/src/app/(admin)/admin/rounds/[id]/assignments/page.tsx index 0987ad9..8826beb 100644 --- a/src/app/(admin)/admin/rounds/[id]/assignments/page.tsx +++ b/src/app/(admin)/admin/rounds/[id]/assignments/page.tsx @@ -16,6 +16,12 @@ import { Skeleton } from '@/components/ui/skeleton' import { Progress } from '@/components/ui/progress' import { Checkbox } from '@/components/ui/checkbox' import { Label } from '@/components/ui/label' +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from '@/components/ui/tabs' import { Table, TableBody, @@ -64,9 +70,125 @@ import { Trash2, RefreshCw, UserPlus, + Cpu, + Brain, } from 'lucide-react' import { toast } from 'sonner' +// Suggestion type for both algorithm and AI suggestions +interface Suggestion { + userId: string + jurorName: string + projectId: string + projectTitle: string + score: number + reasoning: string[] +} + +// Reusable table component for displaying suggestions +function SuggestionsTable({ + suggestions, + selectedSuggestions, + onToggle, + onSelectAll, + onApply, + isApplying, +}: { + suggestions: Suggestion[] + selectedSuggestions: Set- AI Assignment Analysis in Progress -
-- Processing {jobStatus.totalProjects} projects in {jobStatus.totalBatches} batches -
-All projects are covered!
-- No additional assignments are needed at this time -
-No AI analysis yet
++ Click "Start Analysis" to generate AI-powered suggestions +
+All projects are covered!
++ No additional assignments are needed at this time +
+