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() 함수 추가
129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState, useEffect } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import { DashboardHeader } from "./DashboardHeader";
|
|
import { NoticeBanner } from "./NoticeBanner";
|
|
import { KpiBar } from "./KpiBar";
|
|
import { MenuGrid } from "./MenuGrid";
|
|
import { ActivityList } from "./ActivityList";
|
|
import { NoticeList } from "./NoticeList";
|
|
import { DashboardFooter } from "./DashboardFooter";
|
|
import { MenuItem as DashboardMenuItem } from "./types";
|
|
import { menuApi, PopMenuItem } from "@/lib/api/menu";
|
|
import {
|
|
KPI_ITEMS,
|
|
MENU_ITEMS,
|
|
ACTIVITY_ITEMS,
|
|
NOTICE_ITEMS,
|
|
NOTICE_MARQUEE_TEXT,
|
|
} from "./data";
|
|
import "./dashboard.css";
|
|
|
|
const CATEGORY_COLORS: DashboardMenuItem["category"][] = [
|
|
"production",
|
|
"material",
|
|
"quality",
|
|
"equipment",
|
|
"safety",
|
|
];
|
|
|
|
function convertPopMenuToMenuItem(item: PopMenuItem, index: number): DashboardMenuItem {
|
|
return {
|
|
id: item.objid,
|
|
title: item.menu_name_kor,
|
|
count: 0,
|
|
description: item.menu_desc?.replace("[POP]", "").trim() || "",
|
|
status: "",
|
|
category: CATEGORY_COLORS[index % CATEGORY_COLORS.length],
|
|
href: item.menu_url || "#",
|
|
};
|
|
}
|
|
|
|
export function PopDashboard() {
|
|
const router = useRouter();
|
|
const [theme, setTheme] = useState<"dark" | "light">("dark");
|
|
const [menuItems, setMenuItems] = useState<DashboardMenuItem[]>(MENU_ITEMS);
|
|
|
|
useEffect(() => {
|
|
const savedTheme = localStorage.getItem("popTheme") as "dark" | "light" | null;
|
|
if (savedTheme) {
|
|
setTheme(savedTheme);
|
|
}
|
|
}, []);
|
|
|
|
// API에서 POP 메뉴 로드
|
|
useEffect(() => {
|
|
const loadPopMenus = async () => {
|
|
try {
|
|
const response = await menuApi.getPopMenus();
|
|
if (response.success && response.data && response.data.childMenus.length > 0) {
|
|
const converted = response.data.childMenus.map(convertPopMenuToMenuItem);
|
|
setMenuItems(converted);
|
|
}
|
|
} catch {
|
|
// API 실패 시 기존 하드코딩 데이터 유지
|
|
}
|
|
};
|
|
loadPopMenus();
|
|
}, []);
|
|
|
|
const handleThemeToggle = () => {
|
|
const newTheme = theme === "dark" ? "light" : "dark";
|
|
setTheme(newTheme);
|
|
localStorage.setItem("popTheme", newTheme);
|
|
};
|
|
|
|
const handleUserClick = () => {
|
|
if (confirm("로그아웃 하시겠습니까?")) {
|
|
alert("로그아웃되었습니다.");
|
|
}
|
|
};
|
|
|
|
const handlePcModeClick = () => {
|
|
router.push("/");
|
|
};
|
|
|
|
const handleActivityMore = () => {
|
|
alert("전체 활동 내역 화면으로 이동합니다.");
|
|
};
|
|
|
|
const handleNoticeMore = () => {
|
|
alert("전체 공지사항 화면으로 이동합니다.");
|
|
};
|
|
|
|
return (
|
|
<div className={`pop-dashboard-container ${theme === "light" ? "light" : ""}`}>
|
|
<div className="pop-dashboard">
|
|
<DashboardHeader
|
|
theme={theme}
|
|
weather={{ temp: "18°C", description: "맑음" }}
|
|
user={{ name: "김철수", role: "생산1팀", avatar: "김" }}
|
|
company={{ name: "탑씰", subTitle: "현장 관리 시스템" }}
|
|
onThemeToggle={handleThemeToggle}
|
|
onUserClick={handleUserClick}
|
|
onPcModeClick={handlePcModeClick}
|
|
/>
|
|
|
|
<NoticeBanner text={NOTICE_MARQUEE_TEXT} />
|
|
|
|
<KpiBar items={KPI_ITEMS} />
|
|
|
|
<MenuGrid items={menuItems} />
|
|
|
|
<div className="pop-dashboard-bottom-section">
|
|
<ActivityList items={ACTIVITY_ITEMS} onMoreClick={handleActivityMore} />
|
|
<NoticeList items={NOTICE_ITEMS} onMoreClick={handleNoticeMore} />
|
|
</div>
|
|
|
|
<DashboardFooter
|
|
companyName="탑씰"
|
|
version="1.0.0"
|
|
emergencyContact="042-XXX-XXXX"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|