fix(mentor): restore Add Project on mentoring rounds + gate mentor assignment
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m15s

Three related bugs around the mentoring-round Projects tab:

1. Add Project to Round was unreachable on MENTORING rounds — the table swap
   in the prior commit lost the button. Export AddProjectDialog from
   project-states-table and render it inside MentoringProjectsTable with an
   "Add" button in the filter row and a CTA in the empty state.
2. The "Assign Projects" quick action on the round overview linked to the
   global pool with an opaque filter; on MENTORING rounds it now switches
   to the Projects tab where the new Add Project button + auto-fill +
   per-team picker all live. Non-mentoring rounds keep the old behavior.
3. mentor.assign and mentor.bulkAssign now refuse projects that aren't
   enrolled in any MENTORING round (any status). The single-assign throws
   BAD_REQUEST with a guidance message; the bulk path filters them out and
   reports ineligibleProjectCount in the result so the UI can warn the
   admin instead of silently skipping.

Tests: the multi-mentor-assignment suite now sets up a MENTORING round +
ProjectRoundState for each project it tests against, matching the new gate.
This commit is contained in:
Matt
2026-05-26 15:20:01 +02:00
parent c4f7216bc1
commit 61dfc608cd
5 changed files with 183 additions and 27 deletions

View File

@@ -1265,17 +1265,32 @@ export default function RoundDetailPage() {
<div>
<p className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground mb-2">Project Management</p>
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
<Link href={poolLink}>
<button className="flex items-start gap-3 p-4 rounded-lg border hover:-translate-y-0.5 hover:shadow-md transition-all text-left w-full">
{isMentoring ? (
<button
onClick={() => setActiveTab('projects')}
className="flex items-start gap-3 p-4 rounded-lg border hover:-translate-y-0.5 hover:shadow-md transition-all text-left w-full"
>
<Layers className="h-5 w-5 text-[#557f8c] mt-0.5 shrink-0" />
<div>
<p className="text-sm font-medium">Assign Projects</p>
<p className="text-xs text-muted-foreground mt-0.5">
Add projects from the pool to this round
Open the Projects tab to add or auto-fill teams in this round
</p>
</div>
</button>
</Link>
) : (
<Link href={poolLink}>
<button className="flex items-start gap-3 p-4 rounded-lg border hover:-translate-y-0.5 hover:shadow-md transition-all text-left w-full">
<Layers className="h-5 w-5 text-[#557f8c] mt-0.5 shrink-0" />
<div>
<p className="text-sm font-medium">Assign Projects</p>
<p className="text-xs text-muted-foreground mt-0.5">
Add projects from the pool to this round
</p>
</div>
</button>
</Link>
)}
<button
onClick={() => setActiveTab('projects')}
@@ -1595,7 +1610,12 @@ export default function RoundDetailPage() {
{isMentoring && (
<>
<MentoringBulkAssignToolbar roundId={roundId} configJson={config} />
<MentoringProjectsTable roundId={roundId} />
<MentoringProjectsTable
roundId={roundId}
competitionId={competitionId}
competitionRounds={competition?.rounds}
currentSortOrder={round?.sortOrder}
/>
</>
)}
{!isMentoring && (