Decouple projects from rounds with RoundProject join table
Projects now exist at the program level instead of being locked to a single round. A new RoundProject join table enables many-to-many relationships with per-round status tracking. Rounds have sortOrder for configurable progression paths. - Add RoundProject model, programId on Project, sortOrder on Round - Migration preserves existing data (roundId -> RoundProject entries) - Update all routers to query through RoundProject join - Add assign/remove/advance/reorder round endpoints - Add Assign, Advance, Remove Projects dialogs on round detail page - Add round reorder controls (up/down arrows) on rounds list - Show all rounds on project detail page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -132,7 +132,7 @@ export function SubmissionDetailClient() {
|
||||
</Badge>
|
||||
</div>
|
||||
<p className="text-muted-foreground">
|
||||
{project.round.program.year} Edition - {project.round.name}
|
||||
{project.roundProjects?.[0]?.round?.program?.year ? `${project.roundProjects[0].round.program.year} Edition` : ''}{project.roundProjects?.[0]?.round?.name ? ` - ${project.roundProjects[0].round.name}` : ''}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -131,18 +131,24 @@ export function MySubmissionClient() {
|
||||
</Card>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{submissions.map((project) => (
|
||||
{submissions.map((project) => {
|
||||
const latestRoundProject = project.roundProjects?.[0]
|
||||
const projectStatus = latestRoundProject?.status ?? 'SUBMITTED'
|
||||
const roundName = latestRoundProject?.round?.name
|
||||
const programYear = latestRoundProject?.round?.program?.year
|
||||
|
||||
return (
|
||||
<Card key={project.id}>
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<CardTitle className="text-lg">{project.title}</CardTitle>
|
||||
<CardDescription>
|
||||
{project.round.program.year} Edition - {project.round.name}
|
||||
{programYear ? `${programYear} Edition` : ''}{roundName ? ` - ${roundName}` : ''}
|
||||
</CardDescription>
|
||||
</div>
|
||||
<Badge variant={statusColors[project.status] || 'secondary'}>
|
||||
{project.status.replace('_', ' ')}
|
||||
<Badge variant={statusColors[projectStatus] || 'secondary'}>
|
||||
{projectStatus.replace('_', ' ')}
|
||||
</Badge>
|
||||
</div>
|
||||
</CardHeader>
|
||||
@@ -197,22 +203,22 @@ export function MySubmissionClient() {
|
||||
status: 'UNDER_REVIEW',
|
||||
label: 'Under Review',
|
||||
date: null,
|
||||
completed: ['UNDER_REVIEW', 'SEMIFINALIST', 'FINALIST', 'WINNER'].includes(project.status),
|
||||
completed: ['UNDER_REVIEW', 'SEMIFINALIST', 'FINALIST', 'WINNER'].includes(projectStatus),
|
||||
},
|
||||
{
|
||||
status: 'SEMIFINALIST',
|
||||
label: 'Semi-finalist',
|
||||
date: null,
|
||||
completed: ['SEMIFINALIST', 'FINALIST', 'WINNER'].includes(project.status),
|
||||
completed: ['SEMIFINALIST', 'FINALIST', 'WINNER'].includes(projectStatus),
|
||||
},
|
||||
{
|
||||
status: 'FINALIST',
|
||||
label: 'Finalist',
|
||||
date: null,
|
||||
completed: ['FINALIST', 'WINNER'].includes(project.status),
|
||||
completed: ['FINALIST', 'WINNER'].includes(projectStatus),
|
||||
},
|
||||
]}
|
||||
currentStatus={project.status}
|
||||
currentStatus={projectStatus}
|
||||
className="mt-4"
|
||||
/>
|
||||
</div>
|
||||
@@ -229,7 +235,8 @@ export function MySubmissionClient() {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user