-
Notifications
You must be signed in to change notification settings - Fork 77
Open
Labels
Beta-Campaigndifficulty: mediumfrontendhelp wantedExtra attention is neededExtra attention is neededresponsive-design
Description
Robust Tab Visibility & Gating
Objective
Ensure that tabs not explicitly enabled in enabledTabs are completely hidden from every navigation surface in the UI and are entirely unreachable — whether through normal navigation, direct URL entry, browser history, or stale deep links. A disabled tab must leave no visible trace in the interface and must never cause a layout break or unexpected visual shift if accessed directly.
Technical Implementation
Target File
app/(landing)/hackathons/[slug]/page.tsx
Logic Mapping
Navigation Filtering — hackathonTabs useMemo
- Refactor the
hackathonTabsuseMemoto filter thetabsarray againstcurrentHackathon.enabledTabsbefore returning - Only tabs whose identifier exists in the
enabledTabsarray should be included in the memoized result — the filtered array becomes the single source of truth for all navigation rendering - The filter must be data-driven and dynamic — if an organizer enables or disables a tab mid-session, the memoized value should recompute and all navigation surfaces should update accordingly without a hard page reload
- The memo's dependency array must include
currentHackathon.enabledTabsto ensure it recalculates when the configuration changes
Component Guard — Tab Content Section
- In the "Tab Content" section of the page, wrap the rendering of each tab component — including
HackathonResources,AnnouncementsTab,SubmissionTab, and any others — in a conditional check againstcurrentHackathon.enabledTabs - A tab component must not render at all if its identifier is not present in
enabledTabs— not even partially, not even as a loading skeleton - This guard operates as a secondary layer of protection beneath the navigation filtering, ensuring that even if a user reaches a disabled tab via a direct URL or stale link, the component is never instantiated
Deep Linking Gating
- If the
activeTabresolved from the URL query parameter does not exist in the filteredhackathonTabsarray, immediately callsetActiveTab('overview')to default to the overview tab - This must be applied before any tab content renders — the default should be set early enough that the user never sees a flash of an incorrect or empty tab state
- If the
overviewtab is itself disabled (an edge case), handle this gracefully rather than triggering an infinite loop — surface an appropriate fallback rather than repeatedly resetting the active tab
Component Consistency
Mobile Navigation
- The mobile bottom bar and/or mobile drawer menu must apply the same
enabledTabsfiltering as the desktop navigation — disabled tabs must not appear in any mobile navigation surface - Mobile and desktop navigation must remain fully in sync — a tab hidden on desktop must also be hidden on mobile at all times
- Both surfaces should derive their visible tabs from the same filtered
hackathonTabsmemoized value to guarantee consistency and avoid duplicating the filter logic
⚠️ Caution
This is a production environment — not a sandbox.
- Code must be performant, accessible, and clean
- No dummy data — all gating logic must operate on real
enabledTabsvalues fromcurrentHackathon - AI-generated code will be scrutinized; poorly structured or "hallucinated" code will result in immediate issue closure
- Follow the existing design system: shadcn/ui, Tailwind, Framer Motion
Testing & Verification
Automated Tests
npm run lint # Ensure code quality
npm run build # Verify no breaking changes in routing or typesManual Verification
- Confirm the
hackathonTabsuseMemocorrectly filters out tabs not present inenabledTabsand that the filtered result drives all navigation rendering - Verify that
currentHackathon.enabledTabsis included in the memo's dependency array — confirm tabs update dynamically when the configuration changes - Confirm that
HackathonResources,AnnouncementsTab,SubmissionTab, and other tab components do not render at all when their identifier is absent fromenabledTabs - Directly navigate to a disabled tab via URL — confirm
setActiveTab('overview')is called and the overview tab is shown without any flash of the disabled tab's content - Verify the default to
'overview'occurs before any tab content renders — no partial render of the disabled tab should be visible - Simulate an organizer enabling a new tab mid-session — confirm all navigation surfaces update without a hard reload
- Simulate an organizer disabling an active tab mid-session — confirm the tab disappears from all navigation surfaces immediately and direct URL access defaults to overview
- Confirm the mobile bottom bar and drawer menu hide disabled tabs and remain fully in sync with the desktop navigation
- Test with a malformed or unrecognized tab query value in the URL — confirm it falls through to the
'overview'default correctly - Test the edge case where
'overview'itself is disabled — confirm no infinite loop occurs and an appropriate fallback is shown - Provide video evidence
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Beta-Campaigndifficulty: mediumfrontendhelp wantedExtra attention is neededExtra attention is neededresponsive-design