import { useEffect, useState } from 'react' import { BrowserRouter, Routes, Route, Navigate, NavLink, Link, useLocation, useNavigate } from 'react-router-dom' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { Menu, Moon, Sun } from 'lucide-react' import { Button, buttonVariants } from '@/components/ui/button' import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { AuthGate } from '@/components/auth-gate' import { logout } from '@/lib/api' import KeysPage from '@/pages/KeysPage' import PlaygroundPage from '@/pages/PlaygroundPage' import FallbackPage from '@/pages/FallbackPage' import EmbeddingsPage from '@/pages/EmbeddingsPage' import AnalyticsPage from '@/pages/AnalyticsPage' const queryClient = new QueryClient() const navItems = [ { to: '/models', label: 'Models' }, { to: '/playground', label: 'Playground' }, { to: '/keys', label: 'Keys' }, { to: '/analytics', label: 'Analytics' }, ] function getPreferredDarkMode() { if (typeof window === 'undefined') { return false } const stored = localStorage.getItem('theme') return stored === 'dark' || (!stored && window.matchMedia('(prefers-color-scheme: dark)').matches) } function NavItem({ to, children }: { to: string; children: React.ReactNode }) { return ( `relative text-sm px-1 py-4 transition-colors ${ isActive ? 'text-foreground after:absolute after:inset-x-0 after:-bottom-px after:h-px after:bg-foreground' : 'text-muted-foreground hover:text-foreground' }` } > {children} ) } function useDarkMode() { const [dark, setDark] = useState(getPreferredDarkMode) useEffect(() => { document.documentElement.classList.toggle('dark', dark) }, [dark]) function toggle() { setDark((current) => { const next = !current localStorage.setItem('theme', next ? 'dark' : 'light') return next }) } return { dark, toggle } } function DarkModeToggle({ dark, onToggle }: { dark: boolean; onToggle: () => void }) { return ( {dark ? : } ) } function Brand() { return ( FreeLLMAPI ) } // True when the dashboard runs inside the desktop shell (Electron preload // sets this). The navbar then doubles as the window title bar: draggable, // padded for the macOS traffic lights, and without the web-only Sign out. const isDesktopApp = typeof window !== 'undefined' && (window as any).__FREEAPI_DESKTOP__ === true // The preload's own early classList.add can be lost (it may run before this // document exists), so the client claims the class itself at module load — // before the first React paint — keeping html.desktop CSS (transparent body, // glass backdrop) reliable. if (isDesktopApp) { document.documentElement.classList.add('desktop') } function Navbar() { const { dark, toggle } = useDarkMode() const location = useLocation() const navigate = useNavigate() function isActiveRoute(to: string) { return location.pathname === to } return ( {navItems.map((item) => ( {item.label} ))} {!isDesktopApp && ( logout()}> Sign out )} {navItems.map((item) => ( navigate(item.to)} className={isActiveRoute(item.to) ? 'bg-accent text-accent-foreground font-medium' : undefined} > {item.label} ))} Theme {dark ? : } {!isDesktopApp && ( logout()}>Sign out )} ) } function App() { return ( } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ) } export default App