feat(web): add active route highlighting in dashboard sidebar

Use useMatchRoute to mark the current sidebar item and pass isActive
to SidebarMenuButton for visual feedback. Also switch DashboardHeader
to use useLocation for pathname lookup to improve reliability and
align with TanStack Router APIs.
This commit is contained in:
2025-10-07 12:38:21 +07:00
parent 4aa87aee54
commit 757e24d4b3
2 changed files with 23 additions and 13 deletions

View File

@@ -1,4 +1,4 @@
import { useRouter } from "@tanstack/react-router";
import { useLocation, useRouter } from "@tanstack/react-router";
import type { LucideIcon } from "lucide-react";
import {
ArrowLeft,
@@ -51,7 +51,8 @@ const menuItems: readonly MenuItem[] = [
export function DashboardHeader() {
const router = useRouter();
const pathname = router.state.location.pathname;
const location = useLocation();
const pathname = location.pathname;
const getHeaderTitle = () => {
const menuItem = menuItems.find((item) => item.url === pathname);

View File

@@ -1,4 +1,9 @@
import { createFileRoute, Link, Outlet } from "@tanstack/react-router";
import {
createFileRoute,
Link,
Outlet,
useMatchRoute,
} from "@tanstack/react-router";
import type { LucideIcon } from "lucide-react";
import {
ArrowLeft,
@@ -84,6 +89,7 @@ const menuItems: readonly MenuItem[] = [
function RouteComponent() {
const matchRoute = useMatchRoute();
const loaderData = Route.useLoaderData();
if (!loaderData.hasAccess) {
return (
@@ -132,16 +138,19 @@ function RouteComponent() {
<SidebarGroup>
<SidebarGroupContent>
<SidebarMenu>
{menuItems.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<Link to={item.url}>
<item.icon />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
{menuItems.map((item) => {
const isActive = !!matchRoute({ to: item.url, fuzzy: false });
return (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild isActive={isActive}>
<Link to={item.url}>
<item.icon />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
);
})}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>