2026-04-20 14:14:24 +09:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import { usePathname } from "next/navigation";
|
|
|
|
|
import { useMemo } from "react";
|
|
|
|
|
import { useMenu } from "@/contexts/MenuContext";
|
2026-04-20 17:59:28 +09:00
|
|
|
import { useTabStore, selectTabs, selectActiveTabId } from "@/stores/tabStore";
|
2026-04-20 14:14:24 +09:00
|
|
|
|
|
|
|
|
function stripCompanyPrefix(pathname: string): string {
|
|
|
|
|
return pathname.replace(/^\/COMPANY_\d+/, "") || "/";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 현재 경로가 속한 "대분류" 메뉴의 objid 반환.
|
|
|
|
|
* - 메뉴 트리에서 parent_obj_id를 따라 올라가며, 트리에 부모가 더 이상 존재하지 않는 루트 바로 직전의 노드를 반환
|
|
|
|
|
* - lev 필드에 의존하지 않음 (백엔드 재귀 쿼리 결과와 무관)
|
2026-04-20 17:59:28 +09:00
|
|
|
* - 탭 시스템(/main에서 탭으로 페이지를 띄우는 경우) 대응: usePathname이 '/main'을 반환하므로
|
|
|
|
|
* 활성 탭의 adminUrl을 fallback으로 사용
|
2026-04-20 14:14:24 +09:00
|
|
|
*/
|
|
|
|
|
export function useCurrent2ndLevelMenuObjid(): number | null {
|
|
|
|
|
const pathname = usePathname();
|
|
|
|
|
const { userMenus, adminMenus } = useMenu();
|
2026-04-20 17:59:28 +09:00
|
|
|
const tabs = useTabStore(selectTabs);
|
|
|
|
|
const activeTabId = useTabStore(selectActiveTabId);
|
2026-04-20 14:14:24 +09:00
|
|
|
|
|
|
|
|
return useMemo(() => {
|
|
|
|
|
if (!pathname) return null;
|
|
|
|
|
|
|
|
|
|
const all: any[] = [...(userMenus as any[]), ...(adminMenus as any[])];
|
|
|
|
|
if (all.length === 0) return null;
|
|
|
|
|
|
2026-04-20 17:59:28 +09:00
|
|
|
// 1차: 실제 pathname 기준. 2차(탭 컨테이너 경로 등): 활성 탭 URL 기준
|
|
|
|
|
let targetUrl = stripCompanyPrefix(pathname);
|
|
|
|
|
const isRootLikePath = pathname === "/main" || pathname === "/" || pathname === "";
|
|
|
|
|
if (isRootLikePath) {
|
|
|
|
|
const activeTab = tabs.find((t) => t.id === activeTabId);
|
|
|
|
|
if (activeTab?.adminUrl) {
|
|
|
|
|
targetUrl = stripCompanyPrefix(activeTab.adminUrl);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-20 14:14:24 +09:00
|
|
|
|
|
|
|
|
const byObjid = new Map<string, any>();
|
|
|
|
|
for (const m of all) {
|
|
|
|
|
byObjid.set(String(m.objid), m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const current = all.find((m) => m.menu_url === targetUrl);
|
|
|
|
|
if (!current) {
|
|
|
|
|
// eslint-disable-next-line no-console
|
|
|
|
|
console.warn("[useCurrent2ndLevelMenuObjid] 메뉴 매칭 실패", { targetUrl, sample: all.slice(0, 3) });
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let node: any = current;
|
|
|
|
|
let prev: any = null;
|
|
|
|
|
let safety = 20;
|
|
|
|
|
while (node && safety-- > 0) {
|
|
|
|
|
const parentId = node.parent_obj_id;
|
|
|
|
|
if (parentId === null || parentId === undefined || parentId === 0 || parentId === "0") {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
const parent = byObjid.get(String(parentId));
|
|
|
|
|
if (!parent) break;
|
|
|
|
|
prev = node;
|
|
|
|
|
node = parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const resultObjid = prev ? Number(prev.objid) : Number(node.objid);
|
|
|
|
|
// eslint-disable-next-line no-console
|
|
|
|
|
console.log("[useCurrent2ndLevelMenuObjid]", {
|
|
|
|
|
targetUrl,
|
|
|
|
|
currentObjid: current.objid,
|
|
|
|
|
currentName: current.menu_name_kor,
|
|
|
|
|
resultObjid,
|
|
|
|
|
resultName: prev ? prev.menu_name_kor : node.menu_name_kor,
|
|
|
|
|
});
|
|
|
|
|
return resultObjid;
|
2026-04-20 17:59:28 +09:00
|
|
|
}, [pathname, userMenus, adminMenus, tabs, activeTabId]);
|
2026-04-20 14:14:24 +09:00
|
|
|
}
|