fix: version guard uses static file, members table shows project name with round badge
All checks were successful
Build and Push Docker Image / build (push) Successful in 11m12s

Version guard:
- Replace API route with prebuild-generated public/build-id.json
- Captures build ID on first load, only notifies on mismatch
- Fixes false positive refresh prompts from env mismatch

Members table (applicants):
- Show project name + round badge instead of round name + state
- Red badge for rejected, gray for withdrawn, green for passed,
  outline for active rounds
- Include projectName in applicantRoundInfo from backend

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 11:23:24 +01:00
parent 60426c1f56
commit 2e8ab91e07
7 changed files with 36 additions and 30 deletions

View File

@@ -428,20 +428,19 @@ export function MembersContent() {
<div>
{user.role === 'APPLICANT' ? (
(() => {
const info = (user as unknown as { applicantRoundInfo?: { roundName: string; state: string } | null }).applicantRoundInfo
const info = (user as unknown as { applicantRoundInfo?: { projectName: string; roundName: string; state: string } | null }).applicantRoundInfo
if (!info) return <span className="text-sm text-muted-foreground">-</span>
const stateColor = info.state === 'REJECTED' ? 'destructive' as const
: info.state === 'WITHDRAWN' ? 'secondary' as const
: info.state === 'PASSED' ? 'success' as const
: 'default' as const
const stateLabel = info.state === 'IN_PROGRESS' ? 'Active'
: info.state === 'PENDING' ? 'Pending'
: info.state === 'COMPLETED' ? 'Completed'
: 'outline' as const
const stateLabel = info.state === 'REJECTED' ? 'Rejected'
: info.state === 'WITHDRAWN' ? 'Withdrawn'
: info.state === 'PASSED' ? 'Passed'
: info.state
: info.roundName
return (
<div className="flex flex-col gap-0.5">
<span className="text-sm">{info.roundName}</span>
<span className="text-sm font-medium truncate max-w-[200px]">{info.projectName}</span>
<Badge variant={stateColor} className="w-fit text-[10px] px-1.5 py-0">
{stateLabel}
</Badge>
@@ -543,25 +542,24 @@ export function MembersContent() {
</div>
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">
{user.role === 'APPLICANT' ? 'Current Round' : 'Assignments'}
{user.role === 'APPLICANT' ? 'Project' : 'Assignments'}
</span>
<span>
{user.role === 'APPLICANT' ? (
(() => {
const info = (user as unknown as { applicantRoundInfo?: { roundName: string; state: string } | null }).applicantRoundInfo
const info = (user as unknown as { applicantRoundInfo?: { projectName: string; roundName: string; state: string } | null }).applicantRoundInfo
if (!info) return <span className="text-muted-foreground">-</span>
const stateColor = info.state === 'REJECTED' ? 'destructive' as const
: info.state === 'WITHDRAWN' ? 'secondary' as const
: info.state === 'PASSED' ? 'success' as const
: 'default' as const
const stateLabel = info.state === 'IN_PROGRESS' ? 'Active'
: info.state === 'PENDING' ? 'Pending'
: info.state === 'COMPLETED' ? 'Completed'
: 'outline' as const
const stateLabel = info.state === 'REJECTED' ? 'Rejected'
: info.state === 'WITHDRAWN' ? 'Withdrawn'
: info.state === 'PASSED' ? 'Passed'
: info.state
: info.roundName
return (
<span className="flex items-center gap-1.5">
<span>{info.roundName}</span>
<span className="flex flex-col items-end gap-0.5">
<span className="truncate max-w-[160px]">{info.projectName}</span>
<Badge variant={stateColor} className="text-[10px] px-1.5 py-0">
{stateLabel}
</Badge>