import { useEffect, useState } from "react"; import { BrowserRouter, Routes, Route, NavLink } from "react-router-dom"; import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query"; import { api, type Library } from "./api/client"; import BrowserPage from "./pages/BrowserPage"; import SettingsPage from "./pages/SettingsPage"; import SearchPage from "./pages/SearchPage"; const queryClient = new QueryClient(); function useTheme() { const [dark, setDark] = useState( () => document.documentElement.getAttribute("data-theme") === "dark" ); useEffect(() => { document.documentElement.setAttribute("data-theme", dark ? "dark" : "light"); localStorage.setItem("theme", dark ? "dark" : "light"); }, [dark]); return { dark, toggle: () => setDark((d) => !d) }; } function Sidebar({ onToggleTheme, dark, onClose }: { onToggleTheme: () => void; dark: boolean; onClose?: () => void }) { const { data: libraries = [] } = useQuery({ queryKey: ["libraries"], queryFn: api.libraries.list, }); const linkStyle = ({ isActive }: { isActive: boolean }) => ({ display: "block", padding: "6px 12px", textDecoration: "none", borderRadius: 4, color: isActive ? "var(--accent)" : "var(--text)", background: isActive ? "var(--accent-bg)" : "transparent", fontWeight: isActive ? 600 : 400, }); return ( ); } function AppShell() { const { dark, toggle } = useTheme(); const [isMobile, setIsMobile] = useState(() => window.innerWidth < 768); const [sidebarOpen, setSidebarOpen] = useState(false); useEffect(() => { const mq = window.matchMedia("(max-width: 767px)"); setIsMobile(mq.matches); const handler = (e: MediaQueryListEvent) => { setIsMobile(e.matches); if (!e.matches) setSidebarOpen(false); }; mq.addEventListener("change", handler); return () => mq.removeEventListener("change", handler); }, []); return (
{/* Mobile hamburger button */} {isMobile && ( )} {/* Mobile backdrop */} {isMobile && sidebarOpen && (
setSidebarOpen(false)} style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.4)", zIndex: 299 }} /> )} {/* Sidebar */}
setSidebarOpen(false) : undefined} />
} /> } /> } /> } />
); } export default function App() { return ( ); }