--- phase: 27-top-nav-restructure-and-search-bar-rethink plan: 01 type: execute wave: 1 depends_on: [] files_modified: - src/client/components/TopNav.tsx - src/client/components/BottomTabBar.tsx autonomous: true requirements: - NAV-01 - NAV-02 - NAV-03 must_haves: truths: - "TopNav renders logo, Home/Collection/Setups links, search bar, and user avatar on desktop" - "Clicking Collection or Setups while anonymous calls openAuthPrompt instead of navigating" - "Active section is visually highlighted in the nav" - "BottomTabBar renders 4 tabs (Home, Collection, Setups, Search) with Lucide icons on mobile" - "Tapping Search tab calls openCatalogSearch" artifacts: - path: "src/client/components/TopNav.tsx" provides: "Persistent top navigation bar replacing TotalsBar" exports: ["TopNav"] - path: "src/client/components/BottomTabBar.tsx" provides: "Mobile bottom tab bar with 4 navigation items" exports: ["BottomTabBar"] key_links: - from: "src/client/components/TopNav.tsx" to: "src/client/stores/uiStore.ts" via: "openCatalogSearch, openAuthPrompt" pattern: "useUIStore.*openCatalogSearch|useUIStore.*openAuthPrompt" - from: "src/client/components/BottomTabBar.tsx" to: "src/client/stores/uiStore.ts" via: "openCatalogSearch, openAuthPrompt" pattern: "useUIStore.*openCatalogSearch|useUIStore.*openAuthPrompt" --- Create the two new navigation components: TopNav (desktop persistent nav bar) and BottomTabBar (mobile fixed bottom tab bar). Purpose: These components are the core UI deliverables of Phase 27, replacing the minimal TotalsBar with full navigation. They implement D-01 through D-03 (top nav structure), D-07 (nav search bar), D-12 through D-14 (mobile bottom tab bar), and D-17 (search trigger from nav). Output: Two new component files ready to be wired into __root.tsx in Plan 03. @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/27-top-nav-restructure-and-search-bar-rethink/27-CONTEXT.md @.planning/phases/27-top-nav-restructure-and-search-bar-rethink/27-RESEARCH.md From src/client/stores/uiStore.ts: ```typescript openCatalogSearch: (mode: "collection" | "thread") => void; closeCatalogSearch: () => void; openAuthPrompt: () => void; closeAuthPrompt: () => void; ``` From src/client/hooks/useAuth.ts: ```typescript // Returns { data: { user: User | null }, isLoading: boolean } export function useAuth(): UseQueryResult<{ user: User | null }>; ``` From src/client/lib/iconData.tsx: ```typescript // Renders a Lucide icon by name string. Available icons include: package, home, layers, search export function LucideIcon({ name, size, className }: { name: string; size?: number; className?: string }): JSX.Element; ``` From src/client/components/UserMenu.tsx: ```typescript export function UserMenu(): JSX.Element; ``` From src/client/components/TotalsBar.tsx (pattern reference — being replaced): ```typescript // Sticky positioning pattern: "sticky top-0 z-10 bg-white border-b border-gray-100" // Container: "mx-auto max-w-7xl px-4 sm:px-6 lg:px-8" // Height: "h-14" ``` Task 1: Create TopNav component src/client/components/TopNav.tsx src/client/components/TotalsBar.tsx src/client/stores/uiStore.ts src/client/components/UserMenu.tsx src/client/hooks/useAuth.ts Create `src/client/components/TopNav.tsx` that replaces TotalsBar with a full navigation bar. **Structure (per D-01):** - Sticky top bar: `sticky top-0 z-10 bg-white border-b border-gray-100` (same as TotalsBar) - Container: `mx-auto max-w-7xl px-4 sm:px-6 lg:px-8`, flex row, `h-14` - Left: Logo — `` with `` and "GearBox" text. Same styling as TotalsBar logo. - Center: Desktop nav links (hidden on mobile with `hidden md:flex`) — Home, Collection, Setups - Right: Search bar (desktop only) + UserMenu or "Sign in" link **Active route detection (per D-03):** ```typescript const matchRoute = useMatchRoute(); const isHome = !!matchRoute({ to: "/" }); const isCollection = !!matchRoute({ to: "/collection", fuzzy: true }); const isSetups = !!matchRoute({ to: "/setups", fuzzy: true }); ``` Active link gets `text-gray-900`, inactive gets `text-gray-500 hover:text-gray-700`. **Auth-gated nav links (per D-02):** Create a `NavLinkOrButton` internal component. When `isAuthenticated` is false and the link is protected (Collection, Setups), render a `