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 && (