feat(pop): PC <-> POP 모드 전환 네비게이션 + POP 기본 화면(Landing) 기능

PC 모드에서 프로필 드롭다운을 통해 POP 화면으로 진입하고, POP에서 PC로
돌아오는 양방향 네비게이션을 구현한다. 기존 메뉴 시스템(menu_info)을 활용하여
POP 화면의 권한 제어와 회사별 관리가 가능하도록 한다.
[백엔드: POP 메뉴 조회 API]
- AdminService.getPopMenuList: L1 POP 메뉴(menu_desc [POP] 또는
  menu_name_kor POP 포함) 하위의 active L2 메뉴 조회
- company_code 필터링 적용 (L1 + L2 모두)
- landingMenu 반환: menu_desc에 [POP_LANDING] 태그가 있는 메뉴
- GET /admin/pop-menus 라우트 추가
[프론트: PC -> POP 진입]
- AppLayout: handlePopModeClick 함수 추가
  - landingMenu 있으면 해당 URL로 바로 이동
  - 없으면 childMenus 수에 따라 단일 화면/대시보드/안내 분기
- UserDropdown: onPopModeClick prop + "POP 모드" 메뉴 항목 추가
- 사이드바 하단 + 모바일 헤더 프로필 드롭다운 2곳 모두 적용
[프론트: POP -> PC 복귀]
- DashboardHeader: "PC 모드" 버튼 추가 (router.push "/")
- POP 개별 화면 page.tsx: 상단 네비게이션 바 추가
  (POP 대시보드 / PC 모드 버튼)
[프론트: POP 대시보드 동적 메뉴]
- PopDashboard: 하드코딩 MENU_ITEMS -> menuApi.getPopMenus() API 조회
- API 실패 시 하드코딩 fallback 유지
[프론트: POP 기본 화면 설정 (MenuFormModal)]
- L2 POP 화면 수정 시 "POP 기본 화면으로 설정" 체크박스 추가
- 체크 시 menu_desc에 [POP_LANDING] 태그 자동 추가/제거
- 회사당 1개만 설정 가능 (다른 메뉴에 이미 설정 시 비활성화)
[API 타입]
- PopMenuItem, PopMenuResponse(landingMenu 포함) 인터페이스 추가
- menuApi.getPopMenus() 함수 추가
This commit is contained in:
SeongHyun Kim
2026-03-09 12:16:26 +09:00
parent 62e11127a7
commit 3933f1e966
11 changed files with 506 additions and 42 deletions

View File

@@ -107,6 +107,46 @@ export async function getUserMenus(
}
}
/**
* POP 메뉴 목록 조회
* [POP] 태그가 있는 L1 메뉴의 하위 active 메뉴를 반환
*/
export async function getPopMenus(
req: AuthenticatedRequest,
res: Response
): Promise<void> {
try {
const userCompanyCode = req.user?.companyCode || "ILSHIN";
const userType = req.user?.userType;
const result = await AdminService.getPopMenuList({
userCompanyCode,
userType,
});
const response: ApiResponse<any> = {
success: true,
message: "POP 메뉴 목록 조회 성공",
data: result,
};
res.status(200).json(response);
} catch (error) {
logger.error("POP 메뉴 목록 조회 중 오류 발생:", error);
const response: ApiResponse<null> = {
success: false,
message: "POP 메뉴 목록 조회 중 오류가 발생했습니다.",
error: {
code: "POP_MENU_LIST_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
};
res.status(500).json(response);
}
}
/**
* 메뉴 정보 조회
*/