MOTIR-971Done
6.17.7 Public-state header slot — render the active "Building in public" link when public
Estimate: 45m · Type: code · Depends on: 6.17.6
Implement the public-state of the project-shell header build-in-public slot per the 6.17.6 design. When the active project's accessLevel === 'public', render an active "Building in public" indicator in the SAME header slot the BuildInPublicButton CTA occupies when non-public (app/(authed)/_components/TopNav.tsx:82), showing the project is building in public right now and linking to the build-in-public settings (/settings/project/members, the manage/stop home).
app/(authed)/layout.tsx:122-124currently setsbuildInPublicProjectKeytonullonce public. Extend the server-resolved state so the public case is ALSO passed toTopNav(e.g. a{ key, isPublic }shape or a siblingbuildingInPublicProjectKey), keeping the access read server-side (no client access fetch). Keep the existingrouter.refresh()-after-toggle path so the slot swaps states without a hard reload — the slot is server-rendered, sorouter.refresh()reaches it (page-state-after-mutation surface kind 2).TopNav.tsx: render the non-public CTA OR the public linked indicator in the one slot — never both (the stateful single slot).- Reuse
BuildingInPublicBadge(components/projects/BuildingInPublicBadge.tsx) for the visual, wrapping/extending it per 6.17.6 into a NextLinkto/settings/project/memberswith the designed accessible name. - Centralize copy under
settings.buildInPublic.*(en + zh), matching the existing namespace. - Honour the 6.17.6 visibility decision (admins → link; non-admins → per design).
Acceptance criteria
- A public project shows the active "Building in public" indicator in the project-shell header slot; a non-public project still shows the "Start building in public" CTA there; never both.
- Clicking the indicator navigates to
/settings/project/members(the build-in-public manage/stop settings). - Going public / stopping flips the header slot without a hard reload (the existing
router.refresh()path). - Copy lives in
settings.buildInPublic.*for en + zh; the indicator has an accessible name. - A component test covers the public-state render + link target + the non-public↔public toggle (extend
tests/components/build-in-public-entry.test.tsx); the per-file coverage gate holds.
Context refs
app/(authed)/layout.tsx:116-124,app/(authed)/_components/TopNav.tsx:40-93app/(authed)/_components/build-in-public/BuildInPublicButton.tsx(the non-public sibling in the slot)components/projects/BuildingInPublicBadge.tsxapp/(authed)/settings/project/members/page.tsx(nav target)design/public-projects/design-notes.md+public-projects.mock.html(6.17.6 output);messages/en.json/messages/zh.json(settings.buildInPublic.*)