- PermissionContext 기능 확장 (권한 조회 액션 추가) - usePermission 훅 개선 - 회계 모듈 권한 통합: 매입/매출/입금/지출/채권/거래처/어음/일보/부실채권 - 인사 모듈 권한 통합: 근태/카드/급여 관리 - 전자결재 권한 통합: 기안함/결재함 - 게시판/품목/단가/팝업/구독 리스트 권한 적용 - UniversalListPage 권한 연동 - 각 컴포넌트 중복 권한 체크 코드 제거 (-828줄) - 권한 검증 QA 체크리스트 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
81 lines
2.7 KiB
TypeScript
81 lines
2.7 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect } from 'react';
|
|
import { useRouter, usePathname } from 'next/navigation';
|
|
|
|
interface ParentMenuRedirectProps {
|
|
/** 현재 부모 메뉴 경로 (예: '/accounting') */
|
|
parentPath: string;
|
|
/** 메뉴 데이터를 찾지 못했을 때 사용할 기본 첫 번째 자식 경로 */
|
|
fallbackPath: string;
|
|
}
|
|
|
|
/**
|
|
* 부모 메뉴 URL 접근 시 첫 번째 자식 메뉴로 동적 리다이렉트
|
|
*
|
|
* localStorage에 저장된 메뉴 구조를 읽어서 해당 부모의 첫 번째 자식으로 이동합니다.
|
|
* 메뉴 구조가 변경되어도 자동으로 대응됩니다.
|
|
*/
|
|
export function ParentMenuRedirect({ parentPath, fallbackPath }: ParentMenuRedirectProps) {
|
|
const router = useRouter();
|
|
const pathname = usePathname();
|
|
|
|
useEffect(() => {
|
|
try {
|
|
// localStorage에서 user 데이터 읽기
|
|
const userData = localStorage.getItem('user');
|
|
if (!userData) {
|
|
router.replace(fallbackPath);
|
|
return;
|
|
}
|
|
|
|
const parsed = JSON.parse(userData);
|
|
const menuItems = parsed.menu;
|
|
|
|
if (!menuItems || !Array.isArray(menuItems)) {
|
|
router.replace(fallbackPath);
|
|
return;
|
|
}
|
|
|
|
// 현재 부모 메뉴 찾기 (재귀적으로 검색)
|
|
const findParentMenu = (items: any[], targetPath: string): any | null => {
|
|
for (const item of items) {
|
|
// 경로가 일치하는지 확인 (locale prefix 제거 후 비교)
|
|
const itemPath = item.path?.replace(/^\/(ko|en|ja)\//, '/') || '';
|
|
if (itemPath === targetPath || item.path === targetPath) {
|
|
return item;
|
|
}
|
|
// 자식 메뉴에서 검색
|
|
if (item.children && item.children.length > 0) {
|
|
const found = findParentMenu(item.children, targetPath);
|
|
if (found) return found;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const parentMenu = findParentMenu(menuItems, parentPath);
|
|
|
|
if (parentMenu && parentMenu.children && parentMenu.children.length > 0) {
|
|
// 첫 번째 자식 메뉴의 경로로 리다이렉트
|
|
const firstChild = parentMenu.children[0];
|
|
const firstChildPath = firstChild.path?.replace(/^\/(ko|en|ja)\//, '/') || fallbackPath;
|
|
router.replace(firstChildPath);
|
|
} else {
|
|
// 자식이 없으면 fallback으로 이동
|
|
router.replace(fallbackPath);
|
|
}
|
|
} catch (error) {
|
|
console.error('[ParentMenuRedirect] Error:', error);
|
|
router.replace(fallbackPath);
|
|
}
|
|
}, [router, parentPath, fallbackPath]);
|
|
|
|
// 리다이렉트 중 로딩 표시
|
|
return (
|
|
<div className="flex items-center justify-center min-h-[200px]">
|
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
|
</div>
|
|
);
|
|
}
|