Files
invyone/frontend/contexts/MenuContext.tsx
T
DDD1542 2f398ae0b3 chore: 제어모드 IDE 작업 + v2/legacy 레지스트리 컴포넌트 폐기
- 제어모드 IDE: ControlCardPanel, control/ide/* (Canvas/LeftRail/RightRail/PanZoomStage/V3RuleNode 등), schemas, lib/api/control
- 레지스트리 정리: aggregation-widget, status-count, section-card/paper, table-list(legacy/v2), tabs-widget 폐기 → table/_shared/ 로 통합
- InvLegacyButtonConfigPanel cp 마이그레이션
- canonical data view cleanup 후속 노트
2026-05-19 21:31:03 +09:00

99 lines
3.6 KiB
TypeScript

"use client";
import React, { createContext, useContext, useState, useEffect, ReactNode } from "react";
import type { MenuItem } from "@/lib/api/menu";
import { menuApi } from "@/lib/api/menu"; // API 호출 활성화
import { toast } from "sonner";
import { useAuth } from "@/hooks/useAuth"; // user 정보 가져오기
interface MenuContextType {
admin_menus: MenuItem[];
user_menus: MenuItem[];
loading: boolean;
refreshMenus: () => Promise<void>;
}
const MenuContext = createContext<MenuContextType | undefined>(undefined);
export function MenuProvider({ children }: { children: ReactNode }) {
const [adminMenus, setAdminMenus] = useState<MenuItem[]>([]);
const [userMenus, setUserMenus] = useState<MenuItem[]>([]);
const [loading, setLoading] = useState(true);
const { user } = useAuth(); // user 정보 가져오기
const convertMenuData = (data: any[]): MenuItem[] => {
return data.map((item) => ({
objid: item.OBJID ?? item.objid,
parent_obj_id: item.PARENT_OBJ_ID ?? item.parent_obj_id,
menu_name_kor: item.MENU_NAME_KOR || item.menu_name_kor,
menu_url: item.MENU_URL || item.menu_url,
menu_desc: item.MENU_DESC || item.menu_desc,
seq: item.SEQ ?? item.seq,
menu_type: item.MENU_TYPE || item.menu_type,
status: item.STATUS || item.status,
lev: item.LEV ?? item.lev,
lpad_menu_name_kor: item.LPAD_MENU_NAME_KOR || item.lpad_menu_name_kor,
status_title: item.STATUS_TITLE || item.status_title,
writer: item.WRITER || item.writer,
regdate: item.REGDATE || item.regdate,
company_code: item.COMPANY_CODE || item.company_code,
company_name: item.COMPANY_NAME || item.company_name,
// 아이콘 필드
menu_icon: item.MENU_ICON || item.menu_icon,
// 다국어 관련 필드
lang_key: item.LANG_KEY || item.lang_key,
lang_key_desc: item.LANG_KEY_DESC || item.lang_key_desc,
translated_name: item.TRANSLATED_NAME || item.translated_name,
translated_desc: item.TRANSLATED_DESC || item.translated_desc,
}));
};
const loadMenus = async () => {
try {
setLoading(true);
// 관리자 메뉴와 사용자 메뉴를 병렬로 로드
// 좌측 사이드바용: active만 표시
// 로케일은 useAuth.fetchCurrentUser 가 /auth/me 응답에서 세팅 완료 후 user.company_code 가 채워지므로
// 이 함수가 호출되는 시점에는 항상 __GLOBAL_USER_LANG 이 세팅되어 있음 → 별도 대기 불필요
const [adminResponse, userResponse] = await Promise.all([menuApi.getAdminMenus(), menuApi.getUserMenus()]);
if (adminResponse.success && adminResponse.data) {
const convertedAdminMenus = convertMenuData(adminResponse.data);
setAdminMenus(convertedAdminMenus);
}
if (userResponse.success && userResponse.data) {
const convertedUserMenus = convertMenuData(userResponse.data);
setUserMenus(convertedUserMenus);
}
} catch (error) {
console.error("메뉴 로드 오류:", error);
toast.error("메뉴 목록을 불러오는데 실패했습니다.");
} finally {
setLoading(false);
}
};
const refreshMenus = async () => {
await loadMenus();
};
useEffect(() => {
if (!user?.company_code) return;
loadMenus();
}, [user?.company_code]);
return (
<MenuContext.Provider value={{ admin_menus: adminMenus, user_menus: userMenus, loading, refreshMenus }}>{children}</MenuContext.Provider>
);
}
export function useMenu() {
const context = useContext(MenuContext);
if (context === undefined) {
throw new Error("useMenu must be used within a MenuProvider");
}
return context;
}