diff --git a/src/app/(admin)/admin/rounds/[roundId]/page.tsx b/src/app/(admin)/admin/rounds/[roundId]/page.tsx
index c66d2ec..b697727 100644
--- a/src/app/(admin)/admin/rounds/[roundId]/page.tsx
+++ b/src/app/(admin)/admin/rounds/[roundId]/page.tsx
@@ -91,6 +91,7 @@ import { ProjectStatesTable } from '@/components/admin/round/project-states-tabl
// 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 { MentoringRoundOverview } from '@/components/admin/round/mentoring-round-overview'
import { RankingDashboard } from '@/components/admin/round/ranking-dashboard'
import { CoverageReport } from '@/components/admin/assignment/coverage-report'
import { AssignmentPreviewSheet } from '@/components/admin/assignment/assignment-preview-sheet'
@@ -582,6 +583,14 @@ export default function RoundDetailPage() {
const isFiltering = round?.roundType === 'FILTERING'
const isEvaluation = round?.roundType === 'EVALUATION'
const isMentoring = round?.roundType === 'MENTORING'
+
+ // Mentor pool size — used by Round Details panel below to replace the
+ // always-empty "Jury Group" row on MENTORING rounds.
+ const { data: mentorPool } = trpc.mentor.getMentorPool.useQuery(
+ {},
+ { enabled: isMentoring },
+ )
+ const mentorPoolSize = mentorPool?.poolSize ?? 0
const hasJury = ['EVALUATION', 'LIVE_FINAL', 'DELIBERATION'].includes(round?.roundType ?? '')
const hasAwards = roundAwards.length > 0
const isSimpleAdvance = ['INTAKE', 'SUBMISSION', 'MENTORING'].includes(round?.roundType ?? '')
@@ -1469,6 +1478,9 @@ export default function RoundDetailPage() {
/>
)}
+ {/* Mentoring-specific stats \u2014 only on MENTORING rounds */}
+ {isMentoring && }
+
{/* Round Info + Project Breakdown */}
@@ -1482,7 +1494,9 @@ export default function RoundDetailPage() {
{ label: 'Status', value: {statusCfg.label} },
{ label: 'Position', value: {`Round ${(round.sortOrder ?? 0) + 1}${competition?.rounds ? ` of ${competition.rounds.length}` : ''}`} },
...(round.purposeKey ? [{ label: 'Purpose', value: {round.purposeKey} }] : []),
- { label: 'Jury Group', value: {juryGroup ? juryGroup.name : '\u2014'} },
+ isMentoring
+ ? { label: 'Mentor Pool', value: {mentorPoolSize} member{mentorPoolSize === 1 ? '' : 's'} }
+ : { label: 'Jury Group', value: {juryGroup ? juryGroup.name : '\u2014'} },
{ label: 'Opens', value: {round.windowOpenAt ? new Date(round.windowOpenAt).toLocaleString() : '\u2014'} },
{ label: 'Closes', value: {round.windowCloseAt ? new Date(round.windowCloseAt).toLocaleString() : '\u2014'} },
].map((row, i) => (
diff --git a/src/components/admin/round/mentoring-round-overview.tsx b/src/components/admin/round/mentoring-round-overview.tsx
new file mode 100644
index 0000000..992795d
--- /dev/null
+++ b/src/components/admin/round/mentoring-round-overview.tsx
@@ -0,0 +1,217 @@
+'use client'
+
+import Link from 'next/link'
+import { trpc } from '@/lib/trpc/client'
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { Badge } from '@/components/ui/badge'
+import { Skeleton } from '@/components/ui/skeleton'
+import {
+ ArrowRight,
+ Clock,
+ FileText,
+ MessageCircle,
+ Target,
+ UserCheck,
+ Users,
+} from 'lucide-react'
+
+interface Props {
+ roundId: string
+}
+
+function formatRelativeFuture(date: Date | null): { label: string; tone: 'normal' | 'amber' | 'red' } {
+ if (!date) return { label: '—', tone: 'normal' }
+ const ms = date.getTime() - Date.now()
+ if (ms <= 0) return { label: 'Closed', tone: 'red' }
+ const hours = Math.floor(ms / 3_600_000)
+ const days = Math.floor(hours / 24)
+ const tone: 'normal' | 'amber' | 'red' =
+ hours <= 12 ? 'red' : hours <= 48 ? 'amber' : 'normal'
+ const label = days > 0 ? `Closes in ${days}d` : `Closes in ${hours}h`
+ return { label, tone }
+}
+
+function formatRelativePast(date: Date | null): string {
+ if (!date) return '—'
+ const ms = Date.now() - date.getTime()
+ const minutes = Math.floor(ms / 60_000)
+ const hours = Math.floor(ms / 3_600_000)
+ const days = Math.floor(ms / 86_400_000)
+ if (days > 0) return `${days}d ago`
+ if (hours > 0) return `${hours}h ago`
+ return `${Math.max(0, minutes)}m ago`
+}
+
+export function MentoringRoundOverview({ roundId }: Props) {
+ const { data: stats, isLoading: statsLoading } = trpc.mentor.getRoundStats.useQuery(
+ { roundId },
+ { refetchInterval: 30_000 },
+ )
+ const { data: pool, isLoading: poolLoading } = trpc.mentor.getMentorPool.useQuery({})
+
+ if (statsLoading || poolLoading) {
+ return (
+
+ {[1, 2, 3, 4].map((i) => (
+
+ ))}
+
+ )
+ }
+ if (!stats || !pool) return null
+
+ const requestedPct = stats.totalProjects
+ ? Math.round((stats.requestedCount / stats.totalProjects) * 100)
+ : 0
+ const assignedPct = stats.totalProjects
+ ? Math.round((stats.assignedCount / stats.totalProjects) * 100)
+ : 0
+
+ const window = formatRelativeFuture(
+ stats.requestWindow.deadline ? new Date(stats.requestWindow.deadline) : null,
+ )
+
+ const avgLoad =
+ pool.poolSize > 0 ? (pool.totalCurrentAssignments / pool.poolSize).toFixed(1) : '—'
+ const lastActivity = stats.workspaceActivity.lastActivityAt
+ ? new Date(stats.workspaceActivity.lastActivityAt)
+ : null
+
+ return (
+
+
+
+
+ Requested mentoring
+
+
+
+
+ {stats.requestedCount}
+
+ / {stats.totalProjects}
+
+
+ {requestedPct}% of round
+
+
+
+
+
+
+ Mentor assigned
+
+
+
+
+
{stats.assignedCount}
+
+
+
+ {assignedPct}% of round{' '}
+ {stats.awaitingAssignment > 0 && (
+
+ · {stats.awaitingAssignment} awaiting
+
+ )}
+
+
+
+
+
+
+
+ Request window
+
+
+
+
+
+
+ {window.label}
+
+
+
+ {stats.requestWindow.deadline
+ ? `Closes ${new Date(stats.requestWindow.deadline).toLocaleDateString()} · ${stats.requestWindow.deadlineDays}-day window`
+ : 'No window deadline set'}
+
+
+
+
+
+
+
+ Mentor pool
+
+
+ View all
+
+
+
+
+
+
+ Avg load {avgLoad} ·{' '}
+ {pool.totalCurrentAssignments} active
+
+
+
+
+
+
+ Workspace activity
+
+
+
+
+
+
+
{stats.workspaceActivity.messageCount}
+
messages
+
+
+
+
+
+
{stats.workspaceActivity.fileCount}
+
files
+
+
+
+
+
+
+ {stats.workspaceActivity.milestoneCount}
+
+
milestones
+
+
+
+
+
+
{formatRelativePast(lastActivity)}
+
last activity
+
+
+
+
+
+
+ )
+}