diff --git a/surfsense_web/components/sidebar/all-chats-sidebar.tsx b/surfsense_web/components/sidebar/all-chats-sidebar.tsx index 79a811ee1..ef55142fa 100644 --- a/surfsense_web/components/sidebar/all-chats-sidebar.tsx +++ b/surfsense_web/components/sidebar/all-chats-sidebar.tsx @@ -319,7 +319,7 @@ export function AllChatsSidebar({ open, onOpenChange, searchSpaceId }: AllChatsS "group flex items-center gap-2 rounded-md px-2 py-1.5 text-sm", "hover:bg-accent hover:text-accent-foreground", "transition-colors cursor-pointer", - isActive && "bg-accent text-accent-foreground font-medium", + isActive && "bg-accent text-accent-foreground", isBusy && "opacity-50 pointer-events-none" )} > diff --git a/surfsense_web/components/sidebar/all-notes-sidebar.tsx b/surfsense_web/components/sidebar/all-notes-sidebar.tsx index 4f5dee7b8..ff9f07175 100644 --- a/surfsense_web/components/sidebar/all-notes-sidebar.tsx +++ b/surfsense_web/components/sidebar/all-notes-sidebar.tsx @@ -273,7 +273,7 @@ export function AllNotesSidebar({ "group flex items-center gap-2 rounded-md px-2 py-1.5 text-sm", "hover:bg-accent hover:text-accent-foreground", "transition-colors cursor-pointer", - isActive && "bg-accent text-accent-foreground font-medium", + isActive && "bg-accent text-accent-foreground", isDeleting && "opacity-50 pointer-events-none" )} > diff --git a/surfsense_web/components/sidebar/nav-chats.tsx b/surfsense_web/components/sidebar/nav-chats.tsx index 92e814557..3bb7167da 100644 --- a/surfsense_web/components/sidebar/nav-chats.tsx +++ b/surfsense_web/components/sidebar/nav-chats.tsx @@ -153,7 +153,7 @@ export function NavChats({ disabled={isDeletingChat} className={cn( "pr-8", // Make room for the action button - isActive && "bg-sidebar-accent text-sidebar-accent-foreground font-medium", + isActive && "bg-sidebar-accent text-sidebar-accent-foreground", isDeletingChat && "opacity-50" )} > diff --git a/surfsense_web/components/sidebar/nav-main.tsx b/surfsense_web/components/sidebar/nav-main.tsx index 606ab2680..ddb700ff3 100644 --- a/surfsense_web/components/sidebar/nav-main.tsx +++ b/surfsense_web/components/sidebar/nav-main.tsx @@ -1,6 +1,7 @@ "use client"; import { ChevronRight, type LucideIcon } from "lucide-react"; +import { usePathname } from "next/navigation"; import { useTranslations } from "next-intl"; import { useCallback, useMemo, useState } from "react"; @@ -35,6 +36,7 @@ interface NavMainProps { export function NavMain({ items, onSourcesExpandedChange }: NavMainProps) { const t = useTranslations("nav_menu"); + const pathname = usePathname(); // Translation function that handles both exact matches and fallback to original const translateTitle = (title: string): string => { @@ -55,6 +57,32 @@ export function NavMain({ items, onSourcesExpandedChange }: NavMainProps) { return key ? t(key) : title; }; + // Check if an item is active based on pathname + const isItemActive = useCallback((item: NavItem): boolean => { + if (!pathname) return false; + + // For items without sub-items, check if pathname matches or starts with the URL + if (!item.items?.length) { + // Chat item: active ONLY when on new-chat page without a specific chat ID + // (i.e., exactly /dashboard/{id}/new-chat, not /dashboard/{id}/new-chat/123) + if (item.url.includes("/new-chat")) { + // Match exactly the new-chat base URL (ends with /new-chat) + return pathname.endsWith("/new-chat"); + } + // Logs item: active when on logs page + if (item.url.includes("/logs")) { + return pathname.includes("/logs"); + } + // Check exact match or prefix match + return pathname === item.url || pathname.startsWith(`${item.url}/`); + } + + // For items with sub-items (like Sources), check if any sub-item URL matches + return item.items.some( + (subItem) => pathname === subItem.url || pathname.startsWith(subItem.url) + ); + }, [pathname]); + // Memoize items to prevent unnecessary re-renders const memoizedItems = useMemo(() => items, [items]); @@ -88,14 +116,15 @@ export function NavMain({ items, onSourcesExpandedChange }: NavMainProps) { {memoizedItems.map((item, index) => { const translatedTitle = translateTitle(item.title); const hasSub = !!item.items?.length; - const isItemOpen = expandedItems[item.title] ?? item.isActive ?? false; + const isActive = isItemActive(item); + const isItemOpen = expandedItems[item.title] ?? isActive ?? false; return ( handleOpenChange(item.title, open) : undefined} - defaultOpen={!hasSub ? item.isActive : undefined} + defaultOpen={!hasSub ? isActive : undefined} > {hasSub ? ( @@ -105,7 +134,7 @@ export function NavMain({ items, onSourcesExpandedChange }: NavMainProps) {