import { create } from 'zustand'; export interface MenuConfigItem { menuCd: string; parentMenuCd: string | null; menuType: 'ITEM' | 'GROUP' | 'DIVIDER'; urlPath: string | null; rsrcCd: string | null; componentKey: string | null; icon: string | null; labelKey: string | null; dividerLabel: string | null; menuLevel: number; sortOrd: number; useYn: string; labels: Record; } /** DB labels에서 현재 언어의 라벨을 반환 */ export function getMenuLabel(item: MenuConfigItem, lang: string): string { return item.labels?.[lang] || item.labels?.ko || item.menuCd; } interface MenuStore { items: MenuConfigItem[]; loaded: boolean; setMenuConfig: (items: MenuConfigItem[]) => void; clear: () => void; /** path → rsrcCd (longest-match, PATH_TO_RESOURCE 대체) */ getResourceForPath: (path: string) => string | undefined; /** 최상위 항목 (menu_level=0, 사이드바 표시용) */ getTopLevelEntries: () => MenuConfigItem[]; /** 그룹 하위 항목 */ getChildren: (parentMenuCd: string) => MenuConfigItem[]; /** 라우팅 가능 항목 (ITEM + urlPath 보유) */ getRoutableItems: () => MenuConfigItem[]; } export const useMenuStore = create((set, get) => ({ items: [], loaded: false, setMenuConfig: (items) => set({ items, loaded: true }), clear: () => set({ items: [], loaded: false }), getResourceForPath: (path) => { const { items } = get(); // longest-match: 가장 구체적인 경로 우선 (삽입 순서 의존 버그 해결) const candidates = items.filter((i) => i.urlPath && i.rsrcCd); candidates.sort((a, b) => b.urlPath!.length - a.urlPath!.length); const match = candidates.find((i) => path.startsWith(i.urlPath!)); return match?.rsrcCd ?? undefined; }, getTopLevelEntries: () => get().items.filter( (i) => i.menuLevel === 0 && i.parentMenuCd === null && i.useYn !== 'H', ), getChildren: (parentMenuCd) => get().items.filter((i) => i.parentMenuCd === parentMenuCd), getRoutableItems: () => get().items.filter((i) => i.menuType === 'ITEM' && i.urlPath), }));