"use client"; import { useState, useEffect, useCallback } from "react"; import { useSearchParams } from "next/navigation"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { ArrowLeft, Plus, RefreshCw, Search, LayoutGrid, LayoutList } from "lucide-react"; import ScreenList from "@/components/screen/ScreenList"; import ScreenDesigner from "@/components/screen/ScreenDesigner"; import TemplateManager from "@/components/screen/TemplateManager"; import { ScreenGroupTreeView } from "@/components/screen/ScreenGroupTreeView"; import { ScreenRelationFlow } from "@/components/screen/ScreenRelationFlow"; import { ScrollToTop } from "@/components/common/ScrollToTop"; import { ScreenDefinition } from "@/types/screen"; import { screenApi } from "@/lib/api/screen"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import CreateScreenModal from "@/components/screen/CreateScreenModal"; // 단계별 진행을 위한 타입 정의 type Step = "list" | "design" | "template"; type ViewMode = "tree" | "table"; export default function ScreenManagementPage() { const searchParams = useSearchParams(); const [currentStep, setCurrentStep] = useState("list"); const [selectedScreen, setSelectedScreen] = useState(null); const [selectedGroup, setSelectedGroup] = useState<{ id: number; name: string; company_code?: string } | null>(null); const [focusedScreenIdInGroup, setFocusedScreenIdInGroup] = useState(null); const [stepHistory, setStepHistory] = useState(["list"]); const [viewMode, setViewMode] = useState("tree"); const [screens, setScreens] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(""); const [isCreateOpen, setIsCreateOpen] = useState(false); // 화면 목록 로드 const loadScreens = useCallback(async () => { try { setLoading(true); const result = await screenApi.getScreens({ page: 1, size: 1000, searchTerm: "" }); // screenApi.getScreens는 { data: ScreenDefinition[], total, page, size, totalPages } 형태 반환 if (result.data && result.data.length > 0) { setScreens(result.data); } } catch (error) { console.error("화면 목록 로드 실패:", error); } finally { setLoading(false); } }, []); useEffect(() => { loadScreens(); }, [loadScreens]); // 화면 목록 새로고침 이벤트 리스너 useEffect(() => { const handleScreenListRefresh = () => { console.log("🔄 화면 목록 새로고침 이벤트 수신"); loadScreens(); }; window.addEventListener("screen-list-refresh", handleScreenListRefresh); return () => { window.removeEventListener("screen-list-refresh", handleScreenListRefresh); }; }, [loadScreens]); // URL 쿼리 파라미터로 화면 디자이너 자동 열기 useEffect(() => { const openDesignerId = searchParams.get("openDesigner"); if (openDesignerId && screens.length > 0) { const screenId = parseInt(openDesignerId, 10); const targetScreen = screens.find((s) => s.screenId === screenId); if (targetScreen) { setSelectedScreen(targetScreen); setCurrentStep("design"); setStepHistory(["list", "design"]); } } }, [searchParams, screens]); // 화면 설계 모드일 때는 전체 화면 사용 const isDesignMode = currentStep === "design"; // 다음 단계로 이동 const goToNextStep = (nextStep: Step) => { setStepHistory((prev) => [...prev, nextStep]); setCurrentStep(nextStep); }; // 특정 단계로 이동 const goToStep = (step: Step) => { setCurrentStep(step); const stepIndex = stepHistory.findIndex((s) => s === step); if (stepIndex !== -1) { setStepHistory(stepHistory.slice(0, stepIndex + 1)); } }; // 화면 선택 핸들러 (개별 화면 선택 시 그룹 선택 해제) const handleScreenSelect = (screen: ScreenDefinition) => { setSelectedScreen(screen); setSelectedGroup(null); // 그룹 선택 해제 }; // 화면 디자인 핸들러 const handleDesignScreen = (screen: ScreenDefinition) => { setSelectedScreen(screen); goToNextStep("design"); }; // 검색어로 필터링된 화면 const filteredScreens = screens.filter((screen) => screen.screenName.toLowerCase().includes(searchTerm.toLowerCase()) || screen.screenCode.toLowerCase().includes(searchTerm.toLowerCase()) ); // 화면 설계 모드일 때는 레이아웃 없이 전체 화면 사용 if (isDesignMode) { return (
goToStep("list")} />
); } return (
{/* 페이지 헤더 */}

화면 관리

화면을 그룹별로 관리하고 데이터 관계를 확인합니다

{/* 뷰 모드 전환 */} setViewMode(v as ViewMode)}> 트리 테이블
{/* 메인 콘텐츠 */} {viewMode === "tree" ? (
{/* 왼쪽: 트리 구조 */}
{/* 검색 */}
setSearchTerm(e.target.value)} className="pl-9 h-9" />
{/* 트리 뷰 */}
{ setSelectedGroup(group); setSelectedScreen(null); // 화면 선택 해제 setFocusedScreenIdInGroup(null); // 포커스 초기화 }} onScreenSelectInGroup={(group, screenId) => { // 그룹 내 화면 클릭 시 const isNewGroup = selectedGroup?.id !== group.id; if (isNewGroup) { // 새 그룹 진입: 포커싱 없이 시작 (첫 진입 시 망가지는 문제 방지) setSelectedGroup(group); setFocusedScreenIdInGroup(null); } else { // 같은 그룹 내에서 다른 화면 클릭: 포커싱 유지 setFocusedScreenIdInGroup(screenId); } setSelectedScreen(null); }} />
{/* 오른쪽: 관계 시각화 (React Flow) */}
) : ( // 테이블 뷰 (기존 ScreenList 사용)
)} {/* 화면 생성 모달 */} setIsCreateOpen(false)} onSuccess={() => { setIsCreateOpen(false); loadScreens(); }} /> {/* Scroll to Top 버튼 */}
); }