feat(frontend): separate Dashboard from All Hackathons, and drop About from the navbar - #170
Merged
Merged
Conversation
Two distinct labels turned out not to be enough. "Dashboard" and "Hackathons" are both nouns for a list of hackathons and neither word says WHOSE — and the bar's own wordmark reads "Hackathons" too, so the noun appeared twice in one row, once as the platform and once as a page inside it. Pointing the two entries at two destinations (they used to be one entry that changed target with your session) stopped them fighting without making them tellable apart. The pair is separated three ways now instead of one: - the label states the scope — "All Hackathons" against a Dashboard that is yours, one label whoever is asking, because a word that renames itself with your session is the same bug as one that re-points itself; - an icon carries it before the label is read — layout-dashboard for the personal panel, compass for browsing; - a one-line hint spells it out: a `title` on the bar, and VISIBLE text in the mobile panel, where there is no hover for a tooltip to use. About leaves the navbar. The page stays exactly as it is — a CMS-backed, organiser-editable SitePage — and AppFooter's Platform column already links it from every route in both groups, since AppShell mounts that footer for (app) as well as (public). Privacy and Terms are the same kind of page and were never in the bar either. The "every entry present on every page" rule still holds: it forbids an entry that appears and disappears as you move through the app, not one that is consistently absent and linked from the footer instead. 02-login is re-specified rather than trimmed: it asserted About WAS in the bar, so it now asserts the two entries by their new names, counts the bar's links (a third has to argue for itself here first), and adds the claim removal actually rests on — About absent from the header and reachable from the footer on both a public and a signed-in page, clicked rather than merely read off an href. The footer locator is scoped to the Platform column: the SDSC column beside it links datascience.ch's own About, so a footer-wide match finds two links.
…h installs build esbuild's native binary AppShell wrapped the page in min-h-screen + flex-1 on <main>, which stretched the shell to exactly 100vh and pinned the footer to the bottom edge of the viewport even when the page's own content was much shorter — visible on first paint, nothing to scroll. Height is now the natural sum of header + content + footer, so the footer only reaches the fold once real content pushes it there. Verified in a real browser: before the fix the footer's position tracked viewport height 1:1 (pinned to the bottom edge at every height tested); after, it holds a fixed position regardless of viewport height. Also pin esbuild/@tailwindcss/oxide/protobufjs via pnpm.onlyBuiltDependencies so a plain `pnpm install` builds their native binaries instead of silently skipping them (pnpm 10 ignores build scripts by default) -- without this, Vite's dev/build pipeline never starts on a fresh clone. Investigated the reported "no icons in navbar" separately: NavBar.svelte's lucide-svelte icons render correctly in a real headless-Chromium check (desktop nav, mobile panel, and the theme toggle all show correctly sized, correctly colored SVGs) once dependencies are fully installed -- no code change needed there. Claude-Session: https://claude.ai/code/session_01RLLSy37SvMnHE5MUcNy6G5
…ard-hackathons-clarity # Conflicts: # .claude/skills/hackathon-e2e/tests/smoke/02-login.spec.ts
…ard-hackathons-clarity # Conflicts: # components/frontend/src/lib/components/layout/NavBar.svelte
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The logged-in navbar's two primary entries were hard to tell apart. Dashboard and Hackathons are both nouns for a list of hackathons, and neither word says whose — plus the bar's own wordmark reads "Hackathons", so the noun appeared twice in one row: once as the platform, once as a page inside it. History says this has bitten before (the entry once resolved to the dashboard when signed in, making the browse page unreachable from the chrome for anyone with an account). Giving them two destinations stopped them fighting; it did not make them distinguishable.
What changed
components/frontend/src/lib/components/layout/NavBar.svelteonly — no restyling elsewhere.1. The pair is separated three ways instead of one
Dashboard(unchanged)Hackathons→All Hackathonslayout-dashboardcompassaria-hidden), so accessible names are unchanged.titleon the desktop bar and visible text in the mobile panel — a phone has no hover, so a tooltip-only explanation would reach nobody there. Panel rows moved fromh-10tomin-h-10+ padding so the second line cannot be clipped; single-line rows keep their 2.5rem.aria-current="page"), but now spans icon and label.2. About is out of the navbar — the page is untouched
It stays a CMS-backed, organiser-editable SitePage, and it was already linked from
AppFooter's Platform column, whichAppShellrenders for the(app)group as well as(public)— verified, not assumed. Privacy and Terms are the same kind of page and were never in the bar either. The "every entry present on every page" rule still holds: it forbids an entry that appears and disappears as you move through the app, not one that is consistently absent and linked from the footer.Net width at the
mdbreakpoint is roughly unchanged: the icons and the longer label cost about what About's entry freed.3. Specs and docs follow the change
.claude/skills/hackathon-e2e/tests/smoke/02-login.spec.ts— re-specified, not trimmed. It asserted About was in the bar; it now asserts the two entries by their new names, counts the bar's links (so a third entry has to argue for itself here first), and adds the claim this removal actually rests on: About absent from the header and reachable from the footer on both a public and a signed-in page, clicked rather than read off anhref. The footer locator is scoped to the Platform column — the SDSC column beside it linksdatascience.ch's own About, so a footer-wide match resolves two links..claude/CLAUDE.md— the "Nav IA is one meaning per entry" note saidDashboard, Hackathons, About; updated, with why two labels were not enough.Test plan
/aboutreference remaining, both icons imported and used on both surfaces.AppShellmountsAppFooterfor both route groups, and the live footer markup (fetched from the running dev server) carriesPlatform → About → /about.clickLinkinrecipe.jsonltargets the nav entries; the only nav-label couplings in the suite were in02-login, which this PR re-specifies.pnpm check/pnpm lint/pnpm test— not run: this host has no Node/pnpm toolchain and no Docker socket access, and standing up a second devcontainer was ruled out (1.9 GiB RAM, one vCPU, already running a stack). No type-level or branching logic was added — markup, class strings and two icon imports — so CI is the gate here.mdand phone widths, and open the mobile panel (its hint text is the part no static check covers).Noted, not touched (pre-existing)
tests/smoke/21-footer.spec.tslooks stale against the rebuilt footer (0265838), independent of this change: it matches a footer-wideAbout(now two links) and asserts aGitHublink the current footer deliberately does not render. Its own pass, not this one.