Files
sam-react-prod/src/components/common/ParentMenuRedirect.tsx
유병철 17c16028b1 feat(WEB): 리스트 페이지 권한 시스템 통합 및 중복 권한 로직 제거
- PermissionContext 기능 확장 (권한 조회 액션 추가)
- usePermission 훅 개선
- 회계 모듈 권한 통합: 매입/매출/입금/지출/채권/거래처/어음/일보/부실채권
- 인사 모듈 권한 통합: 근태/카드/급여 관리
- 전자결재 권한 통합: 기안함/결재함
- 게시판/품목/단가/팝업/구독 리스트 권한 적용
- UniversalListPage 권한 연동
- 각 컴포넌트 중복 권한 체크 코드 제거 (-828줄)
- 권한 검증 QA 체크리스트 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 16:46:48 +09:00

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>
);
}