diff --git a/src/components/applicant/competition-timeline.tsx b/src/components/applicant/competition-timeline.tsx index a5273e6..4ab5e34 100644 --- a/src/components/applicant/competition-timeline.tsx +++ b/src/components/applicant/competition-timeline.tsx @@ -202,15 +202,16 @@ export function CompetitionTimelineSidebar() { // Is this entry after the elimination point? const isAfterElimination = eliminationIndex >= 0 && index > eliminationIndex - // Is this the current round? Either has an active project state, - // or is the first round the project hasn't passed yet (for seed data - // where project states may be missing). + // Is this the current round? Either the project has an active state + // here, or every previous round has an explicit advancement outcome + // (PASSED/COMPLETED). A closed round alone isn't enough — a round can + // close before admins declare advancement, and until they do, the + // applicant has NOT moved on to the next round. const hasActiveProjectState = !!entry.projectState && entry.projectState !== 'PASSED' && entry.projectState !== 'COMPLETED' && entry.projectState !== 'REJECTED' const isCurrent = !isAfterElimination && (hasActiveProjectState || ( !isPassed && !isRejected && !isCompleted && data.entries.slice(0, index).every((prev) => - prev.projectState === 'PASSED' || prev.projectState === 'COMPLETED' || - prev.status === 'ROUND_CLOSED' || prev.status === 'ROUND_ARCHIVED' + prev.projectState === 'PASSED' || prev.projectState === 'COMPLETED' ) && index > 0 ))