feat: 사이드바 메뉴 클릭 핸들러 작업

This commit is contained in:
2025-03-31 10:40:00 +09:00
parent 84519658c1
commit 7860345e89
3 changed files with 47 additions and 7 deletions
+9 -2
View File
@@ -1,11 +1,18 @@
"use client";
import { usePathname, useRouter } from "next/navigation";
import { BaseLayout } from "@common/components/ui";
export default function WithBaseLayout({
children,
}: {
children: React.ReactNode;
}) {
return <BaseLayout>{children}</BaseLayout>;
const router = useRouter();
const pathname = usePathname();
return (
<BaseLayout currentPath={pathname ?? ""} routeHandler={router.push}>
{children}
</BaseLayout>
);
}
@@ -10,9 +10,13 @@ import type { QueryClient } from "@tanstack/react-query";
export function BaseLayout({
children,
queryClient,
currentPath,
routeHandler,
}: {
children: React.ReactNode;
queryClient?: QueryClient;
currentPath?: string;
routeHandler?: (path: string) => void;
}) {
return (
<QueryProvider client={queryClient}>
@@ -20,7 +24,7 @@ export function BaseLayout({
<div className="flex-1">
<Header />
<div className="flex h-[calc(100vh-50px)]">
<LNB />
<LNB currentPath={currentPath} routeHandler={routeHandler} />
<div className="flex flex-1 flex-col">
<div className="max-h-[calc(100%-50px)] flex-1 overflow-auto">
{children}
@@ -1,7 +1,7 @@
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { ChevronRight } from "lucide-react";
import { cn } from "../../lib/utils";
import { cn, setCookie } from "../../lib";
import { ENDPOINT, SITE_ID } from "../../config";
import { getMenuList, type MenuItem } from "../../api";
import {
@@ -19,7 +19,15 @@ import {
} from "../collapsible";
import { getParentIds } from "./lib";
export function LNB({ viewOnly }: { viewOnly?: boolean }) {
export function LNB({
viewOnly,
currentPath,
routeHandler,
}: {
viewOnly?: boolean;
currentPath?: string;
routeHandler?: (path: string) => void;
}) {
const { data: menuList } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES],
queryFn: () => getMenuList(SITE_ID),
@@ -28,14 +36,31 @@ export function LNB({ viewOnly }: { viewOnly?: boolean }) {
const [openMenuIds, setOpenMenuIds] = useState<number[]>([]);
function isPathMatched(path: string) {
return currentPath === path || currentPath?.startsWith(`${path}/`);
}
function MenuItem({ item }: { item: MenuItem }) {
const isMatched = isPathMatched(item.urlPath);
const handleClick = () => {
setCookie("menu-code-key", item.menuCd.toString());
routeHandler?.(item.urlPath);
};
if (item.children) {
return <MenuGroup item={item} />;
}
return (
<SidebarMenuItem>
<SidebarMenuButton className="h-auto py-4 text-[1.4rem] text-label transition-colors hover:bg-accent">
<SidebarMenuButton
className={cn(
"h-auto py-4 text-[1.4rem] text-label transition-colors hover:bg-accent",
isMatched && "bg-accent text-primary",
)}
onClick={handleClick}
>
<i className={cn("diveicon ml-2", `di-${item.iconNm}`)} />
{item.menuKornNm}
</SidebarMenuButton>
@@ -44,7 +69,11 @@ export function LNB({ viewOnly }: { viewOnly?: boolean }) {
}
function MenuGroup({ item }: { item: MenuItem }) {
const isOpen = openMenuIds.includes(item.menuCd);
const hasMatchedChild = item.children?.some((child) =>
isPathMatched(child.urlPath),
);
const isOpen = openMenuIds.includes(item.menuCd) || hasMatchedChild;
const handleOpenChange = (open: boolean) => {
if (open) {