feat: 사이드바 메뉴 클릭 핸들러 작업
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user