diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index c54aca28..ae95d4c6 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -10,7 +10,7 @@ import { ListOrgsResponse } from "@server/routers/org"; import SupporterStatus from "@app/components/SupporterStatus"; import { Separator } from "@app/components/ui/separator"; import { Button } from "@app/components/ui/button"; -import { ExternalLink, Menu, X } from "lucide-react"; +import { ExternalLink, Menu, X, Server } from "lucide-react"; import { Sheet, SheetContent, @@ -21,6 +21,7 @@ import { import { useEnvContext } from "@app/hooks/useEnvContext"; import { Breadcrumbs } from "@app/components/Breadcrumbs"; import Link from "next/link"; +import { usePathname } from "next/navigation"; interface LayoutProps { children: React.ReactNode; @@ -54,6 +55,8 @@ export function Layout({ }: LayoutProps) { const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); const { env } = useEnvContext(); + const pathname = usePathname(); + const isAdminPage = pathname?.startsWith("/admin"); return (
@@ -85,7 +88,26 @@ export function Layout({
)}
- setIsMobileMenuOpen(false)} /> + + setIsMobileMenuOpen(false) + } + /> + {!isAdminPage && ( +
+ + setIsMobileMenuOpen(false) + } + > + + Server Admin + +
+ )}
@@ -109,8 +131,21 @@ export function Layout({
)} -
- +
+
+ +
+ {!isAdminPage && ( +
+ + + Server Admin + +
+ )}
@@ -124,7 +159,7 @@ export function Layout({ className="flex items-center justify-center gap-1" > Open Source - +
{env?.app?.version && ( diff --git a/src/components/SidebarNav.tsx b/src/components/SidebarNav.tsx index 0d2c15af..effdaf85 100644 --- a/src/components/SidebarNav.tsx +++ b/src/components/SidebarNav.tsx @@ -5,6 +5,7 @@ import Link from "next/link"; import { useParams, usePathname } from "next/navigation"; import { cn } from "@app/lib/cn"; import { ChevronDown, ChevronRight } from "lucide-react"; +import { useUserContext } from "@app/hooks/useUserContext"; export interface SidebarNavItem { href: string; @@ -35,6 +36,8 @@ export function SidebarNav({ const userId = params.userId as string; const [expandedItems, setExpandedItems] = useState>(new Set()); + const { user } = useUserContext(); + function hydrateHref(val: string): string { return val .replace("{orgId}", orgId) @@ -47,19 +50,22 @@ export function SidebarNav({ useEffect(() => { const autoExpanded = new Set(); - function findAutoExpandedAndActivePath(items: SidebarNavItem[], parentHrefs: string[] = []) { - items.forEach(item => { + function findAutoExpandedAndActivePath( + items: SidebarNavItem[], + parentHrefs: string[] = [] + ) { + items.forEach((item) => { const hydratedHref = hydrateHref(item.href); - + // Add current item's href to the path const currentPath = [...parentHrefs, hydratedHref]; - + // Auto expand if specified or if this item or any child is active if (item.autoExpand || pathname.startsWith(hydratedHref)) { // Expand all parent sections when a child is active - currentPath.forEach(href => autoExpanded.add(href)); + currentPath.forEach((href) => autoExpanded.add(href)); } - + // Recursively check children if (item.children) { findAutoExpandedAndActivePath(item.children, currentPath); @@ -72,7 +78,7 @@ export function SidebarNav({ }, [items, pathname]); function toggleItem(href: string) { - setExpandedItems(prev => { + setExpandedItems((prev) => { const newSet = new Set(prev); if (newSet.has(href)) { newSet.delete(href); @@ -93,7 +99,10 @@ export function SidebarNav({ return (
-
+
- {item.icon && {item.icon}} + {item.icon && ( + + {item.icon} + + )} {item.title} {hasChildren && (