From 942b60a7ff2708255b2c12df3ed4bce51c301cd5 Mon Sep 17 00:00:00 2001 From: Hannah Casey <61227037+hanaCasey@users.noreply.github.com> Date: Thu, 13 Aug 2026 14:12:15 +0000 Subject: [PATCH 1/2] fix(frontend): make the hackathon manage sidebar flat, not collapsible The Manage section folded its screens under Manage Hackathon behind a chevron, but the fold force-opened on every /manage/* route (entering the section opens it) - so navigating to any manage screen always rendered the full list anyway, inside a sidebar with a fixed viewport-relative height, forcing it to scroll. Revert to rendering manageNav's full item list flat, as before the fold was introduced: drop manageOpen/insideManage state, the hub/sub-item split, and the SidebarNavSection open/onToggle wiring. SidebarNavSection itself is untouched and simply renders a plain list when no parentItem is passed. The unrelated --consent-banner-h padding and overflow-y-auto safety net on the nav are left in place. --- .../components/layout/HackathonSidebar.svelte | 40 ++-------- .../layout/HackathonSidebar.test.ts | 74 ++++++++----------- 2 files changed, 34 insertions(+), 80 deletions(-) diff --git a/components/frontend/src/lib/components/layout/HackathonSidebar.svelte b/components/frontend/src/lib/components/layout/HackathonSidebar.svelte index 03dfbc59..d0c968be 100644 --- a/components/frontend/src/lib/components/layout/HackathonSidebar.svelte +++ b/components/frontend/src/lib/components/layout/HackathonSidebar.svelte @@ -42,11 +42,6 @@ let collapsed = $state(false); let mobileOpen = $state(false); let isDesktop = $state(true); - // Closed to start with, leaving Manage Hackathon alone under the heading: a - // participant spine plus one way in, not a second nav half again as long as - // the first on every page whether or not the organiser came to manage - // anything. Ten organiser entries sat flat under the heading before this. - let manageOpen = $state(false); // `collapsed` is a desktop-only preference (persisted below); on a narrow // viewport the drawer must always render fully expanded regardless of it. @@ -66,15 +61,6 @@ // Manage Pages. const activeId = $derived(activeNavId($page.url.pathname, [...items, ...manageItems])); - // The hub stays on the rail whatever the fold state and carries the - // disclosure for the rest — it is how the section is entered. - const manageHubItem = $derived(manageItems.find((i) => i.id === 'manage:hackathon')); - const manageSubItems = $derived(manageItems.filter((i) => i.id !== 'manage:hackathon')); - - // The hub counts as inside, not just the screens under it: opening it is how - // an organiser goes looking for the rest. - const insideManage = $derived(activeId?.startsWith('manage:') ?? false); - // `membership.role` is sourced from casbin. It is absent for a global admin who // never joined, hence the second argument. const badge = $derived(hackathonRoleBadge(membership ?? undefined, isGlobalAdmin)); @@ -82,14 +68,6 @@ $effect(() => { if (typeof localStorage === 'undefined') return; collapsed = localStorage.getItem('sidebar-collapsed') === 'true'; - manageOpen = localStorage.getItem('sidebar-manage-open') === 'true'; - }); - - // Entering the section opens it, rather than pinning it open while you are in - // there: deriving the fold state from the route instead made the chevron a - // no-op on every Manage page, which reads as a broken control. - $effect(() => { - if (insideManage) manageOpen = true; }); $effect(() => { @@ -129,11 +107,6 @@ collapsed = !collapsed; remember('sidebar-collapsed', collapsed); } - - function toggleManage() { - manageOpen = !manageOpen; - remember('sidebar-manage-open', manageOpen); - }