From 4f3efacb9004475851b7a62bc168c5f95405b08a Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Sun, 23 Aug 2026 10:41:09 +0200 Subject: [PATCH] fix(projects): hide help labels after submissions close Suppress looking-for-help badges in both project overview layouts once a year's submissions are closed. Open years and other ProjectCard consumers retain the existing display behavior. Add route coverage for closed-year grid and list views. --- src/app/components/ProjectCard.tsx | 20 ++++++++++++++++---- src/app/routes/ProjectsPage.tsx | 1 + test/app/routes.test.tsx | 26 ++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/app/components/ProjectCard.tsx b/src/app/components/ProjectCard.tsx index 60c1362..5a30965 100644 --- a/src/app/components/ProjectCard.tsx +++ b/src/app/components/ProjectCard.tsx @@ -15,11 +15,13 @@ export function ProjectCard({ view = 'grid', voteCategories = [], detailsSearch, + showHelpLabel = true, }: { project: ProjectSummary; view?: 'grid' | 'list'; voteCategories?: string[]; detailsSearch?: string; + showHelpLabel?: boolean; }) { const projectLink = `/years/${project.yearId}/projects/${project.id}${detailsSearch ? `?${detailsSearch}` : ''}`; @@ -31,7 +33,7 @@ export function ProjectCard({ kind={project.kind} groupName={project.group?.name ?? 'ungrouped'} members={project.members} - needsHelp={project.needsHelp} + needsHelp={showHelpLabel && project.needsHelp} hasVideo={project.hasVideo} voteCategories={voteCategories} /> @@ -40,7 +42,7 @@ export function ProjectCard({ return (
- +

{project.name}

@@ -122,14 +124,24 @@ function ProjectVoteBadge({categories}: {categories: string[]}) { ); } -function ProjectTags({project, className}: {project: ProjectSummary; className: string}) { +function ProjectTags({ + project, + className, + showHelpLabel, +}: { + project: ProjectSummary; + className: string; + showHelpLabel: boolean; +}) { return (
{project.kind === 'idea' ? 'open idea' : (project.group?.name ?? 'ungrouped')} - {project.needsHelp && looking for help} + {showHelpLabel && project.needsHelp && ( + looking for help + )}
); } diff --git a/src/app/routes/ProjectsPage.tsx b/src/app/routes/ProjectsPage.tsx index af85667..2c3f81e 100644 --- a/src/app/routes/ProjectsPage.tsx +++ b/src/app/routes/ProjectsPage.tsx @@ -339,6 +339,7 @@ export function ProjectsPage({isAdmin = false}: {isAdmin?: boolean}) { project={project} view={view} voteCategories={voteCategoriesByProject.get(project.id)} + showHelpLabel={!year.data.year.submissionsClosed} detailsSearch={ kind === 'project' && group ? `group=${encodeURIComponent(group)}` diff --git a/test/app/routes.test.tsx b/test/app/routes.test.tsx index 9c5ed6e..19f9368 100644 --- a/test/app/routes.test.tsx +++ b/test/app/routes.test.tsx @@ -601,7 +601,11 @@ describe('clickable project routes', () => { }); it('keeps closed-year browsing and ballot read failures local', async () => { - mockProjectsOverview({votingEnabled: false, projects: [projectFixture]}); + mockProjectsOverview({ + votingEnabled: false, + submissionsClosed: true, + projects: [projectFixture], + }); const closed = renderRoute( , '/years/2026/projects', @@ -627,6 +631,22 @@ describe('clickable project routes', () => { expect(screen.queryByRole('heading', {name: 'Something went wrong'})).toBeNull(); }); + it('hides help labels in both overview views when submissions are closed', async () => { + mockProjectsOverview({ + votingEnabled: false, + submissionsClosed: true, + projects: [{...projectFixture, needsHelp: true}], + }); + + renderRoute(, '/years/2026/projects', '/years/:yearId/projects'); + + await screen.findByRole('heading', {name: 'A small machine'}); + expect(screen.queryByText('looking for help')).toBeNull(); + + await userEvent.click(screen.getByRole('button', {name: 'list view'})); + expect(screen.queryByText('looking for help')).toBeNull(); + }); + it('defaults to the grid view when storage is unavailable', async () => { fetchMock.mockImplementation(async (input) => { const url = input instanceof Request ? input.url : input.toString(); @@ -2038,6 +2058,7 @@ function mockProjectDetails({ function mockProjectsOverview({ votingEnabled = true, + submissionsClosed = false, categories = [], votes = [], projects = [], @@ -2045,6 +2066,7 @@ function mockProjectsOverview({ ballotError = false, }: { votingEnabled?: boolean; + submissionsClosed?: boolean; categories?: Array<{id: string; yearId: string; name: string}>; votes?: BallotStatusResponse['votes']; projects?: ProjectDetail[]; @@ -2058,7 +2080,7 @@ function mockProjectsOverview({ year: { id: '2026', votingEnabled, - submissionsClosed: false, + submissionsClosed, isCurrent: true, projectCount: projects.length, ideaCount: 0,