'use client'; import * as React from 'react'; import { usePathname } from 'next/navigation'; import DatasetSidebar from '@/components/datasets/DatasetSidebar'; import Header from '@/components/shell/Header'; import { HeaderActionsProvider } from '@/components/shell/HeaderActionsContext'; import PrimarySidebar from '@/components/shell/PrimarySidebar'; import JobDetailsSidebar from '@/components/jobs/JobDetailsSidebar'; import { Toaster } from '@/components/ui/sonner'; import { useMediaQuery } from '@/hooks/useMediaQuery'; import { useStore } from '@/hooks/useStore'; import { activeDatasetStore, setActiveDatasetId, } from '@/stores/activeDataset'; import { activeJobStore, setActiveJobId } from '@/stores/activeJob'; import { initDefaultOptions } from '@/stores/defaultOptions'; const JOB_ROUTES = ['/inference', '/finetuning', '/distillation']; export function AppShell({ children }: { children: React.ReactNode }) { const pathname = usePathname(); const { activeJob } = useStore(activeJobStore); const { activeDataset } = useStore(activeDatasetStore); const isMobile = useMediaQuery('(max-width: 767px)'); const [primaryWidth, setPrimaryWidth] = React.useState(220); const [secondaryWidth, setSecondaryWidth] = React.useState(0); const [primaryOpen, setPrimaryOpen] = React.useState(false); const jobSidebarOpen = JOB_ROUTES.includes(pathname) && activeJob != null; const datasetSidebarOpen = pathname === '/datasets' && activeDataset != null; const secondaryOpen = jobSidebarOpen || datasetSidebarOpen; // Mobile detail drawers claim aria-modal, so everything behind them must // actually be inert — the platform enforces what the ARIA claims. const drawerModal = isMobile && secondaryOpen; React.useEffect(() => { initDefaultOptions(); }, []); React.useEffect(() => { setPrimaryOpen(false); }, [pathname]); React.useEffect(() => { function handleKeyDown(e: KeyboardEvent) { if (e.key !== 'Escape' || document.querySelector('[data-modal]')) return; if (primaryOpen) { setPrimaryOpen(false); return; } if (activeJobStore.get().activeJob) setActiveJobId(null); if (activeDatasetStore.get().activeDataset) setActiveDatasetId(null); } document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); }, [primaryOpen]); return (
setPrimaryOpen((open) => !open)} />
setPrimaryOpen(false)} onWidthChange={setPrimaryWidth} /> {primaryOpen && (
); }