T5/Phase 3: SPA shell + navigation

- TanStack Router with type-safe file-based routes
- Sidebar: collapsible, workspace switcher, 12 nav links, user menu
- Topbar: search, quick-add, notifications, user avatar
- cmdk command palette: nav + create + search + @mentions
- Keyboard shortcuts: Cmd+K palette, g+t/h/p/n/c/g/s navigation, ? help
- Theme: dark default, accent picker (slate/blue/green/purple/orange), persisted to localStorage
- Auth: login -> /, logout -> /login, 401 redirect
- Placeholder pages for all 13 nav routes (real in T6/T7)
- Typed API client with useApiQuery/useApiMutation hooks
This commit is contained in:
Hermes
2026-08-01 02:00:24 +00:00
parent c277e3a14f
commit e86a7c0672
66 changed files with 3781 additions and 32 deletions
+35
View File
@@ -0,0 +1,35 @@
import { createRoute, Outlet } from "@tanstack/react-router";
import { Route as rootRoute } from "./__root";
import { Sidebar } from "@/components/shell/sidebar";
import { Topbar } from "@/components/shell/topbar";
import { CommandPalette } from "@/components/shell/command-palette";
import { ShortcutsHelp } from "@/components/shell/shortcuts-help";
import { useKeyboardShortcuts } from "@/hooks/use-keyboard-shortcuts";
function AppLayout() {
useKeyboardShortcuts();
return (
<div className="flex min-h-screen">
<Sidebar />
<div className="flex flex-1 flex-col">
<Topbar />
<main
id="main-content"
className="flex-1 overflow-auto p-4 md:p-6"
tabIndex={-1}
>
<Outlet />
</main>
</div>
<CommandPalette />
<ShortcutsHelp />
</div>
);
}
export const Route = createRoute({
getParentRoute: () => rootRoute,
id: "_app",
component: AppLayout,
});