"use client"; import React from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Separator } from "@/components/ui/separator"; import { Table, Search, FileText, Grid3x3, Info, FormInput, Save, X, Trash2, Edit, Plus, RotateCcw, Send, ExternalLink, MousePointer, Settings, Upload, } from "lucide-react"; // 템플릿 컴포넌트 타입 정의 export interface TemplateComponent { id: string; name: string; description: string; category: "table" | "button" | "form" | "layout" | "chart" | "status" | "file"; icon: React.ReactNode; defaultSize: { width: number; height: number }; components: Array<{ type: "widget" | "container" | "datatable" | "file"; widgetType?: string; label: string; placeholder?: string; position: { x: number; y: number }; size: { width: number; height: number }; style?: any; required?: boolean; readonly?: boolean; }>; } // 미리 정의된 템플릿 컴포넌트들 const templateComponents: TemplateComponent[] = [ // 고급 데이터 테이블 템플릿 { id: "advanced-data-table", name: "고급 데이터 테이블", description: "컬럼 설정, 필터링, 페이지네이션이 포함된 완전한 데이터 테이블", category: "table", icon: , defaultSize: { width: 1000, height: 680 }, components: [ // 데이터 테이블 컴포넌트 (특별한 타입) { type: "datatable", label: "데이터 테이블", position: { x: 0, y: 0 }, size: { width: 1000, height: 680 }, style: { border: "1px solid #e5e7eb", borderRadius: "8px", backgroundColor: "#ffffff", padding: "16px", }, }, ], }, // 범용 버튼 템플릿 { id: "universal-button", name: "버튼", description: "다양한 기능을 설정할 수 있는 범용 버튼. 상세설정에서 기능을 선택하세요.", category: "button", icon: , defaultSize: { width: 80, height: 36 }, components: [ { type: "widget", widgetType: "button", label: "버튼", position: { x: 0, y: 0 }, size: { width: 80, height: 36 }, style: { backgroundColor: "#3b82f6", color: "#ffffff", border: "none", borderRadius: "6px", fontSize: "14px", fontWeight: "500", }, }, ], }, // 파일 첨부 템플릿 { id: "file-upload", name: "파일 첨부", description: "파일 업로드, 미리보기, 다운로드가 가능한 파일 첨부 컴포넌트", category: "file", icon: , defaultSize: { width: 600, height: 300 }, components: [ { type: "file", label: "파일 첨부", position: { x: 0, y: 0 }, size: { width: 600, height: 300 }, style: { border: "1px solid #e5e7eb", borderRadius: "8px", backgroundColor: "#ffffff", padding: "16px", }, }, ], }, ]; interface TemplatesPanelProps { onDragStart: (e: React.DragEvent, template: TemplateComponent) => void; } export const TemplatesPanel: React.FC = ({ onDragStart }) => { const [searchTerm, setSearchTerm] = React.useState(""); const [selectedCategory, setSelectedCategory] = React.useState("all"); const categories = [ { id: "all", name: "전체", icon: }, { id: "table", name: "테이블", icon:
}, { id: "button", name: "버튼", icon: }, { id: "file", name: "파일", icon: }, ]; const filteredTemplates = templateComponents.filter((template) => { const matchesSearch = template.name.toLowerCase().includes(searchTerm.toLowerCase()) || template.description.toLowerCase().includes(searchTerm.toLowerCase()); const matchesCategory = selectedCategory === "all" || template.category === selectedCategory; return matchesSearch && matchesCategory; }); return (
{/* 검색 */}
setSearchTerm(e.target.value)} className="pl-10" />
{/* 카테고리 필터 */}
{categories.map((category) => ( ))}
{/* 템플릿 목록 */}
{filteredTemplates.length === 0 ? (

검색 결과가 없습니다

) : ( filteredTemplates.map((template) => (
onDragStart(e, template)} className="group cursor-move rounded-lg border border-gray-200 bg-white p-3 shadow-sm transition-all hover:border-blue-300 hover:shadow-md" >
{template.icon}

{template.name}

{template.components.length}개

{template.description}

{template.defaultSize.width}×{template.defaultSize.height} {template.category}
)) )}
{/* 도움말 */}

사용 방법

템플릿을 캔버스로 드래그하여 빠르게 화면을 구성하세요.

); }; export default TemplatesPanel;