import { Outlet, NavLink, useNavigate, Link, useLocation } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { useAuth } from "../hooks/useAuth"; import SearchBar from "./SearchBar"; import { getDownloads, getChannels } from "../api"; function DownloadIndicator() { const { data } = useQuery({ queryKey: ["downloads"], queryFn: () => getDownloads().then((r) => r.data), refetchInterval: (query) => { const active = (query.state.data ?? []).some( (d) => d.status === "pending" || d.status === "downloading" ); return active ? 1500 : 10_000; }, }); const active = (data ?? []).filter( (d) => d.status === "pending" || d.status === "downloading" ); if (!active.length) return null; const top = active[0]; const pct = top.progress_percent ?? 0; return ( 1 ? "s" : ""} in progress`} > {pct.toFixed(0)}% {active.length > 1 && ( +{active.length - 1} )} ); } function NavItem({ to, children, badge }) { return ( `relative px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${ isActive ? "bg-zinc-800 text-zinc-100" : "text-zinc-400 hover:text-zinc-100 hover:bg-zinc-800/60" }` } > {children} {badge > 0 && ( {badge > 99 ? "99+" : badge} )} ); } function DropItem({ to, children, badge }) { return ( `relative flex items-center justify-between gap-4 px-3 py-2 text-sm rounded-lg mx-1 transition-colors ${ isActive ? "bg-zinc-800 text-zinc-100" : "text-zinc-400 hover:text-zinc-100 hover:bg-zinc-800/60" }` } > {children} {badge > 0 && ( {badge > 99 ? "99+" : badge} )} ); } function NavDropdown({ label, paths, children }) { const location = useLocation(); const isGroupActive = paths.some(p => location.pathname.startsWith(p)); return (
{/* invisible bridge so mouse can move from button to panel without gap */}
{children}
); } function NavDivider() { return
; } function useNewVideosCount() { const { data: channels = [] } = useQuery({ queryKey: ["channels"], queryFn: () => getChannels().then((r) => r.data), staleTime: 60_000, }); return channels.reduce((sum, c) => sum + (c.new_count ?? 0), 0); } export default function Layout() { const { user, logout } = useAuth(); const navigate = useNavigate(); const newCount = useNewVideosCount(); return (
{/* Header */}
{/* Logo */} {/* Search */}
{/* Active downloads indicator */} {/* Nav */} {/* User */}
{/* Page content */}
); }