diff --git a/frontend/app/(main)/admin/screenMng/screenMngList/page.tsx b/frontend/app/(main)/admin/screenMng/screenMngList/page.tsx index 0b74b2ee..450e836a 100644 --- a/frontend/app/(main)/admin/screenMng/screenMngList/page.tsx +++ b/frontend/app/(main)/admin/screenMng/screenMngList/page.tsx @@ -4,7 +4,7 @@ import { useState, useEffect, useCallback, useMemo } from "react"; import { useSearchParams } from "next/navigation"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import { Plus, RefreshCw, Search, LayoutGrid, LayoutList, TestTube2, Monitor, MoreHorizontal, PanelLeftClose, PanelLeftOpen } from "lucide-react"; +import { Plus, RefreshCw, Search, LayoutGrid, LayoutList, TestTube2, Database, MoreHorizontal, PanelLeftClose, PanelLeftOpen } from "lucide-react"; import ScreenDesigner from "@/components/screen/ScreenDesigner"; import TemplateManager from "@/components/screen/TemplateManager"; import { ScreenGroupTreeView } from "@/components/screen/ScreenGroupTreeView"; @@ -300,25 +300,42 @@ export default function ScreenManagementPage() { ) : (
-
+
{filteredScreens.map((screen) => (
handleScreenSelect(screen)} onDoubleClick={() => handleDesignScreen(screen)} > -
- -
-
-
{screen.screenName}
-
{screen.screenCode}
-
- {screen.tableName || "테이블 없음"} + {/* 상단: 상태 dot + 이름 + 호버 편집 */} +
+ +
+
{screen.screenName}
+
{screen.screenCode}
+ 편집 +
+ {/* 중단: 메타 정보 */} +
+ + + {screen.tableName || "—"} + +
+ {/* 하단: 타입 칩 + 날짜 */} +
+ + {(screen as { screenType?: string }).screenType === "grid" ? "그리드" : (screen as { screenType?: string }).screenType === "dashboard" ? "대시보드" : "폼"} + + + {screen.createdDate ? new Date(screen.createdDate).toLocaleDateString("ko-KR", { month: "2-digit", day: "2-digit" }) : ""} +
))} diff --git a/frontend/components/screen/ScreenNode.tsx b/frontend/components/screen/ScreenNode.tsx index 119f6944..4e7bfbb5 100644 --- a/frontend/components/screen/ScreenNode.tsx +++ b/frontend/components/screen/ScreenNode.tsx @@ -22,8 +22,8 @@ if (typeof document !== "undefined") { style.id = styleId; style.textContent = ` @keyframes glow-pulse { - from { filter: drop-shadow(0 0 6px hsl(221.2 83.2% 53.3% / 0.4)) drop-shadow(0 0 14px hsl(221.2 83.2% 53.3% / 0.2)); } - to { filter: drop-shadow(0 0 10px hsl(221.2 83.2% 53.3% / 0.6)) drop-shadow(0 0 22px hsl(221.2 83.2% 53.3% / 0.3)); } + from { filter: drop-shadow(0 0 4px hsl(var(--primary) / 0.25)) drop-shadow(0 0 10px hsl(var(--primary) / 0.12)); } + to { filter: drop-shadow(0 0 6px hsl(var(--primary) / 0.35)) drop-shadow(0 0 16px hsl(var(--primary) / 0.18)); } } `; document.head.appendChild(style); @@ -122,42 +122,14 @@ const getScreenTypeIcon = (screenType?: string) => { } }; -// 화면 타입별 색상 (헤더) - 그라데이션 -const getScreenTypeColor = (screenType?: string, isMain?: boolean) => { - if (!isMain) return "bg-gradient-to-r from-muted-foreground to-muted-foreground/80"; - switch (screenType) { - case "grid": - return "bg-gradient-to-r from-primary to-primary/80"; - case "dashboard": - return "bg-gradient-to-r from-warning to-warning/80"; - case "action": - return "bg-gradient-to-r from-destructive to-destructive/80"; - default: - return "bg-gradient-to-r from-primary to-primary/80"; - } +// 화면 타입별 색상 (헤더) - 더 이상 그라데이션 미사용 +const getScreenTypeColor = (_screenType?: string, _isMain?: boolean) => { + return ""; }; -// 화면 역할(screenRole)에 따른 색상 - 그라데이션 -const getScreenRoleColor = (screenRole?: string) => { - if (!screenRole) return "bg-gradient-to-r from-muted-foreground to-muted-foreground/80"; - - // 역할명에 포함된 키워드로 색상 결정 - const role = screenRole.toLowerCase(); - - if (role.includes("그리드") || role.includes("grid") || role.includes("메인") || role.includes("main") || role.includes("list")) { - return "bg-gradient-to-r from-primary to-primary/80"; // 메인 그리드 - } - if (role.includes("등록") || role.includes("폼") || role.includes("form") || role.includes("register") || role.includes("input")) { - return "bg-gradient-to-r from-primary to-primary/80"; // 등록 폼 - } - if (role.includes("액션") || role.includes("action") || role.includes("이벤트") || role.includes("event") || role.includes("클릭")) { - return "bg-gradient-to-r from-destructive to-destructive/80"; // 액션/이벤트 - } - if (role.includes("상세") || role.includes("detail") || role.includes("popup") || role.includes("팝업")) { - return "bg-gradient-to-r from-warning to-warning/80"; // 상세/팝업 - } - - return "bg-gradient-to-r from-muted-foreground to-muted-foreground/80"; // 기본 회색 +// 화면 역할(screenRole)에 따른 색상 - 더 이상 그라데이션 미사용 +const getScreenRoleColor = (_screenRole?: string) => { + return ""; }; // 화면 타입별 라벨 @@ -176,31 +148,17 @@ const getScreenTypeLabel = (screenType?: string) => { // ========== 화면 노드 (상단) - 미리보기 표시 ========== export const ScreenNode: React.FC<{ data: ScreenNodeData }> = ({ data }) => { - const { label, subLabel, isMain, tableName, layoutSummary, isInGroup, isFocused, isFaded, screenRole } = data; + const { label, isMain, tableName, layoutSummary, isFocused, isFaded } = data; const screenType = layoutSummary?.screenType || "form"; - - // 그룹 모드에서는 screenRole 기반 색상, 그렇지 않으면 screenType 기반 색상 - // isFocused일 때 색상 활성화, isFaded일 때 회색 - let headerColor: string; - if (isInGroup) { - if (isFaded) { - headerColor = "bg-gradient-to-r from-muted to-muted/60"; // 흑백 처리 - 더 확실한 회색 - } else { - // 포커스되었거나 아직 아무것도 선택 안됐을 때: 역할별 색상 - headerColor = getScreenRoleColor(screenRole); - } - } else { - headerColor = getScreenTypeColor(screenType, isMain); - } return (
= ({ data }) => { type="target" position={Position.Left} id="left" - className="!h-2.5 !w-2.5 !border-2 !border-background !bg-primary opacity-0 transition-all duration-300 group-hover:opacity-100 group-hover:shadow-[0_0_6px_hsl(var(--primary)/0.5)]" + className="!h-2 !w-2 !border-[1.5px] !border-card !bg-muted-foreground/40 opacity-0 transition-all duration-300 group-hover:opacity-100 group-hover:shadow-[0_0_6px_hsl(var(--primary)/0.5)]" /> - {/* 헤더 (컬러) */} -
-
+ {/* 헤더: 그라디언트 제거, 모노크롬 */} +
+
-
{label}
- {tableName &&
{tableName}
} +
{label}
+ {tableName &&
{tableName}
}
- {(isMain || isFocused) && } + {(isMain || isFocused) && }
{/* 화면 미리보기 영역 (컴팩트) */} -
+
{layoutSummary ? ( ) : ( -
+
{getScreenTypeIcon(screenType)} 화면: {label}
)}
- {/* 푸터 (타입 + 컴포넌트 수) */} -
- {getScreenTypeLabel(screenType)} + {/* 푸터 (타입 칩 + 컴포넌트 수) */} +
+ {getScreenTypeLabel(screenType)} {layoutSummary?.totalComponents ?? 0}개 컴포넌트
@@ -306,114 +264,114 @@ const ScreenPreview: React.FC<{ layoutSummary: ScreenLayoutSummary; screenType: }) => { const { totalComponents, widgetCounts } = layoutSummary; - // 그리드 화면 일러스트 + // 그리드 화면 일러스트 (모노크롬) if (screenType === "grid") { - return ( -
+ return ( +
{/* 상단 툴바 */}
-
+
-
-
-
+
+
+
{/* 테이블 헤더 */} -
+
{[...Array(5)].map((_, i) => ( -
+
))}
{/* 테이블 행들 */}
{[...Array(7)].map((_, i) => ( -
+
{[...Array(5)].map((_, j) => ( -
+
))}
))}
{/* 페이지네이션 */}
-
-
-
-
+
+
+
+
); } - // 폼 화면 일러스트 + // 폼 화면 일러스트 (모노크롬) if (screenType === "form") { return ( -
+
{/* 폼 필드들 */} {[...Array(6)].map((_, i) => (
-
-
+
+
))} {/* 버튼 영역 */} -
-
-
+
+
+
); } - // 대시보드 화면 일러스트 + // 대시보드 화면 일러스트 (모노크롬) if (screenType === "dashboard") { return ( -
+
{/* 카드/차트들 */} -
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
{[...Array(10)].map((_, i) => (
))}
-
+
); } - // 액션 화면 일러스트 (버튼 중심) + // 액션 화면 일러스트 (모노크롬) if (screenType === "action") { return ( -
-
+
+
-
+
-
-
-
+
+
+
액션 화면
); } - // 기본 (알 수 없는 타입) + // 기본 (알 수 없는 타입, 모노크롬) return ( -
-
+
+
{getScreenTypeIcon(screenType)}
{totalComponents}개 컴포넌트