import { Link, Outlet, useLocation } from "@tanstack/react-router"; import { useEffect, useRef, useState } from "react"; import { useAtomRefresh, useAtomValue, Result } from "@effect-atom/atom-react"; import { sourcesAtom, toolsAtom } from "@executor/react/api/atoms"; import { useScope } from "@executor/react/api/scope-context"; import { Button } from "@executor/react/components/button"; import { AUTH_PATHS } from "../auth/api"; import { useAuth } from "./auth"; // ── NavItem ────────────────────────────────────────────────────────────── function NavItem(props: { to: string; label: string; active: boolean; onNavigate?: () => void }) { return ( {props.label} ); } // ── SourceList ─────────────────────────────────────────────────────────── function SourceList(props: { pathname: string; onNavigate?: () => void }) { const scopeId = useScope(); const sources = useAtomValue(sourcesAtom(scopeId)); return Result.match(sources, { onInitial: () => (
Loading…
), onFailure: () => (
No sources yet
), onSuccess: ({ value }) => value.length === 0 ? (
No sources yet
) : (
{value.map((s) => { const detailPath = `/sources/${s.id}`; const active = props.pathname === detailPath || props.pathname.startsWith(`${detailPath}/`); return ( {s.name} {s.kind} ); })}
), }); } // ── UserFooter ────────────────────────────────────────────────────────── function UserFooter() { const auth = useAuth(); if (auth.status !== "authenticated") return null; const initials = auth.user.name ? auth.user.name.split(" ").map((n) => n[0]).join("").slice(0, 2).toUpperCase() : auth.user.email[0]!.toUpperCase(); return (
{auth.user.avatarUrl ? ( ) : (
{initials}
)}

{auth.user.name ?? auth.user.email}

{auth.team && (

{auth.team.name}

)}
); } // ── SidebarContent ─────────────────────────────────────────────────────── function SidebarContent(props: { pathname: string; onNavigate?: () => void; showBrand?: boolean; }) { const isHome = props.pathname === "/"; const isSecrets = props.pathname === "/secrets"; return ( <> {props.showBrand !== false && (
executor
)} ); } // ── Shell ───────────────────────────────────────────────────────────────── export function Shell() { const location = useLocation(); const pathname = location.pathname; const scopeId = useScope(); const refreshSources = useAtomRefresh(sourcesAtom(scopeId)); const refreshTools = useAtomRefresh(toolsAtom(scopeId)); const lastPathname = useRef(pathname); const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); if (lastPathname.current !== pathname) { lastPathname.current = pathname; if (mobileSidebarOpen) setMobileSidebarOpen(false); } // Lock scroll when mobile sidebar open useEffect(() => { if (!mobileSidebarOpen) return; const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = prev; }; }, [mobileSidebarOpen]); return (
{/* Desktop sidebar */} {/* Mobile sidebar overlay */} {mobileSidebarOpen && (
setMobileSidebarOpen(false)} showBrand={false} />
)} {/* Main content */}
{/* Mobile top bar */}
executor
); }