diff --git a/src/app/(admin)/admin/rounds/[roundId]/page.tsx b/src/app/(admin)/admin/rounds/[roundId]/page.tsx index 78b4632..c66d2ec 100644 --- a/src/app/(admin)/admin/rounds/[roundId]/page.tsx +++ b/src/app/(admin)/admin/rounds/[roundId]/page.tsx @@ -145,6 +145,73 @@ const stateColors: Record = Object.fromEntries( Object.entries(projectStateConfig).map(([k, v]) => [k, v.bg]) ) +// ═══════════════════════════════════════════════════════════════════════════ +// Mentoring round: Auto-fill remaining toolbar (Projects tab) +// ═══════════════════════════════════════════════════════════════════════════ + +function MentoringBulkAssignToolbar({ + roundId, + configJson, +}: { + roundId: string + configJson: Record +}) { + const utils = trpc.useUtils() + const eligibility = (configJson.eligibility as string) ?? 'requested_only' + const isAdminSelected = eligibility === 'admin_selected' + + const { data: pending } = trpc.round.getProjectsNeedingMentor.useQuery( + { roundId }, + { enabled: !isAdminSelected, refetchInterval: 30_000 }, + ) + const count = pending?.count ?? 0 + + const bulk = trpc.mentor.autoAssignBulkForRound.useMutation({ + onSuccess: (result) => { + toast.success(result.message) + utils.round.getProjectsNeedingMentor.invalidate({ roundId }) + utils.project.list.invalidate() + }, + onError: (err) => toast.error(err.message), + }) + + const eligibilityLabel = eligibility.replace('_', ' ') + + return ( +
+
+ {isAdminSelected ? ( + <> + Eligibility: admin-selected + + — auto-fill is disabled. Assign each project manually. + + + ) : count > 0 ? ( + <> + {count}{' '} + + project{count === 1 ? '' : 's'} eligible for auto-fill ({eligibilityLabel}) + + + ) : ( + + All eligible projects have a mentor. + + )} +
+ +
+ ) +} + // ═══════════════════════════════════════════════════════════════════════════ // Main Page Component // ═══════════════════════════════════════════════════════════════════════════ @@ -1477,6 +1544,9 @@ export default function RoundDetailPage() { {/* ═══════════ PROJECTS TAB ═══════════ */} + {isMentoring && ( + + )} { + const round = await ctx.prisma.round.findUniqueOrThrow({ + where: { id: input.roundId }, + select: { roundType: true, configJson: true }, + }) + if (round.roundType !== 'MENTORING') return { count: 0 } + const config = (round.configJson ?? {}) as Record + const eligibility = (config.eligibility as string) ?? 'requested_only' + if (eligibility === 'admin_selected') return { count: 0 } + + const count = await ctx.prisma.projectRoundState.count({ + where: { + roundId: input.roundId, + project: { + mentorAssignment: null, + ...(eligibility === 'requested_only' ? { wantsMentorship: true } : {}), + }, + }, + }) + return { count } + }), + /** * Delete a round */