diff --git a/web/src/App.tsx b/web/src/App.tsx index b688899e3..51530c132 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -6,7 +6,14 @@ import { type ComponentType, type ReactNode, } from "react"; -import { Routes, Route, NavLink, Navigate, useNavigate } from "react-router-dom"; +import { + Routes, + Route, + NavLink, + Navigate, + useLocation, + useNavigate, +} from "react-router-dom"; import { Activity, BarChart3, @@ -44,6 +51,7 @@ import { PageHeaderProvider } from "@/contexts/PageHeaderProvider"; import { useSystemActions } from "@/contexts/useSystemActions"; import type { SystemAction } from "@/contexts/system-actions-context"; import ConfigPage from "@/pages/ConfigPage"; +import DocsPage from "@/pages/DocsPage"; import EnvPage from "@/pages/EnvPage"; import SessionsPage from "@/pages/SessionsPage"; import LogsPage from "@/pages/LogsPage"; @@ -57,9 +65,6 @@ import { PluginPage, PluginSlot, usePlugins } from "@/plugins"; import type { PluginManifest } from "@/plugins"; import { useTheme } from "@/themes"; -/** Canonical public docs (Docusaurus). */ -const HERMES_DOCS_URL = "https://hermes-agent.nousresearch.com/docs/"; - function RootRedirect() { return ; } @@ -74,6 +79,7 @@ const BUILTIN_ROUTES: Record = { "/skills": SkillsPage, "/config": ConfigPage, "/env": EnvPage, + "/docs": DocsPage, }; const BUILTIN_NAV: NavItem[] = [ @@ -95,11 +101,10 @@ const BUILTIN_NAV: NavItem[] = [ { path: "/config", labelKey: "config", label: "Config", icon: Settings }, { path: "/env", labelKey: "keys", label: "Keys", icon: KeyRound }, { - path: "nav:docs", + path: "/docs", labelKey: "documentation", label: "Documentation", icon: BookOpen, - href: HERMES_DOCS_URL, }, ]; @@ -222,10 +227,12 @@ function buildRoutes(manifests: PluginManifest[]): Array<{ export default function App() { const { t } = useI18n(); + const { pathname } = useLocation(); const { manifests } = usePlugins(); const { theme } = useTheme(); const [mobileOpen, setMobileOpen] = useState(false); const closeMobile = useCallback(() => setMobileOpen(false), []); + const isDocsRoute = pathname === "/docs" || pathname === "/docs/"; const navItems = useMemo( () => buildNavItems(BUILTIN_NAV, manifests), @@ -384,34 +391,34 @@ export default function App() { aria-label={t.app.navigation} > @@ -491,14 +465,20 @@ export default function App() {
-
+
{routes.map(({ key, path, element }) => ( @@ -633,7 +613,6 @@ function SidebarSystemActions({ onNavigate }: { onNavigate: () => void }) { } interface NavItem { - href?: string; icon: ComponentType<{ className?: string }>; label: string; labelKey?: string; diff --git a/web/src/components/ui/button.tsx b/web/src/components/ui/button.tsx index f8e10a6cf..8f2f27206 100644 --- a/web/src/components/ui/button.tsx +++ b/web/src/components/ui/button.tsx @@ -1,7 +1,7 @@ import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; -const buttonVariants = cva( +export const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap font-mondwest text-xs tracking-[0.1em] uppercase transition-colors cursor-pointer" + " disabled:pointer-events-none disabled:opacity-50", { diff --git a/web/src/contexts/PageHeaderProvider.tsx b/web/src/contexts/PageHeaderProvider.tsx index d4ae647d6..fce5852a0 100644 --- a/web/src/contexts/PageHeaderProvider.tsx +++ b/web/src/contexts/PageHeaderProvider.tsx @@ -79,7 +79,7 @@ export function PageHeaderProvider({
{children}
diff --git a/web/src/lib/resolve-page-title.ts b/web/src/lib/resolve-page-title.ts index 49feb3cb1..7d8cfd1ba 100644 --- a/web/src/lib/resolve-page-title.ts +++ b/web/src/lib/resolve-page-title.ts @@ -8,6 +8,7 @@ const BUILTIN: Record = { "/skills": "skills", "/config": "config", "/env": "keys", + "/docs": "documentation", }; export function resolvePageTitle( diff --git a/web/src/pages/DocsPage.tsx b/web/src/pages/DocsPage.tsx new file mode 100644 index 000000000..83b0694ec --- /dev/null +++ b/web/src/pages/DocsPage.tsx @@ -0,0 +1,54 @@ +import { useLayoutEffect } from "react"; +import { ExternalLink } from "lucide-react"; +import { useI18n } from "@/i18n"; +import { usePageHeader } from "@/contexts/usePageHeader"; +import { buttonVariants } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; + +export const HERMES_DOCS_URL = "https://hermes-agent.nousresearch.com/docs/"; + +export default function DocsPage() { + const { t } = useI18n(); + const { setEnd } = usePageHeader(); + + useLayoutEffect(() => { + setEnd( + + + {t.app.openDocumentation} + , + ); + return () => { + setEnd(null); + }; + }, [setEnd, t]); + + return ( +
+