// Sticky top navigation bar. Adapts based on whether we're on the repo picker // page (root) or inside a specific repo: // - Root: shows logo only, no Code/Issues links // - Repo: shows Code + Issues nav links scoped to the current repo slug // // In external mode, shows a "Sign in" button when logged out and a sign-out // action when logged in. import { Link, useMatch, NavLink } from 'react-router-dom' import { Bug, Plus, Sun, Moon, LogIn, LogOut } from 'lucide-react' import { cn } from '@/lib/utils' import { useAuth } from '@/lib/auth' import { useTheme } from '@/lib/theme' import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' import { Button } from '@/components/ui/button' // SignOutButton sends a POST to /auth/logout and reloads the page. // A full reload is the simplest way to reset all Apollo cache + React state. function SignOutButton() { function handleSignOut() { fetch('/auth/logout', { method: 'POST', credentials: 'include' }).finally( () => window.location.assign('/'), ) } return ( ) } export function Header() { const { user, mode, loginProviders } = useAuth() const { theme, toggle } = useTheme() // Detect if we're inside a /:repo route and grab the slug. // useMatch works from any component in the tree, unlike useParams which is // scoped to the nearest Route element. const repoMatch = useMatch({ path: '/:repo/*', end: false }) const repo = repoMatch?.params.repo ?? null // Don't show repo nav on the /auth/* pages. const effectiveRepo = repo === 'auth' ? null : repo return (
{/* Logo always goes to the repo picker root */} git-bug {/* Repo-scoped nav links — only shown when inside a repo */} {effectiveRepo && ( )}
{mode === 'readonly' && ( Read only )} {/* External mode: show sign-in buttons when logged out */} {mode === 'external' && !user && loginProviders.map((p) => ( ))} {user && effectiveRepo && ( <> {user.displayName.slice(0, 2).toUpperCase()} )} {/* Sign out only shown in external mode when logged in */} {mode === 'external' && user && }
) } function providerLabel(name: string): string { const labels: Record = { github: 'GitHub', gitlab: 'GitLab', gitea: 'Gitea' } return labels[name] ?? name }