"use client"; import React, { useState, useEffect, useCallback } from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Checkbox } from "@/components/ui/checkbox"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; import { FileComponent } from "@/types/screen"; import { Plus, X } from "lucide-react"; import { Button } from "@/components/ui/button"; interface FileComponentConfigPanelProps { component: FileComponent; onUpdateProperty: (componentId: string, path: string, value: any) => void; } export const FileComponentConfigPanel: React.FC = ({ component, onUpdateProperty }) => { // 로컬 상태 const [localInputs, setLocalInputs] = useState({ docType: component.fileConfig.docType || "DOCUMENT", docTypeName: component.fileConfig.docTypeName || "일반 문서", dragDropText: component.fileConfig.dragDropText || "파일을 드래그하거나 클릭하여 업로드하세요", maxSize: component.fileConfig.maxSize || 10, maxFiles: component.fileConfig.maxFiles || 5, newAcceptType: "", // 새 파일 타입 추가용 }); const [localValues, setLocalValues] = useState({ multiple: component.fileConfig.multiple ?? true, showPreview: component.fileConfig.showPreview ?? true, showProgress: component.fileConfig.showProgress ?? true, }); const [acceptTypes, setAcceptTypes] = useState(component.fileConfig.accept || []); // 컴포넌트 변경 시 로컬 상태 동기화 useEffect(() => { setLocalInputs({ docType: component.fileConfig.docType || "DOCUMENT", docTypeName: component.fileConfig.docTypeName || "일반 문서", dragDropText: component.fileConfig.dragDropText || "파일을 드래그하거나 클릭하여 업로드하세요", maxSize: component.fileConfig.maxSize || 10, maxFiles: component.fileConfig.maxFiles || 5, newAcceptType: "", }); setLocalValues({ multiple: component.fileConfig.multiple ?? true, showPreview: component.fileConfig.showPreview ?? true, showProgress: component.fileConfig.showProgress ?? true, }); setAcceptTypes(component.fileConfig.accept || []); }, [component.fileConfig]); // 미리 정의된 문서 타입들 const docTypeOptions = [ { value: "CONTRACT", label: "계약서" }, { value: "DRAWING", label: "도면" }, { value: "PHOTO", label: "사진" }, { value: "DOCUMENT", label: "일반 문서" }, { value: "REPORT", label: "보고서" }, { value: "SPECIFICATION", label: "사양서" }, { value: "MANUAL", label: "매뉴얼" }, { value: "CERTIFICATE", label: "인증서" }, { value: "OTHER", label: "기타" }, ]; // 미리 정의된 파일 타입들 const commonFileTypes = [ { value: "image/*", label: "모든 이미지 파일" }, { value: ".pdf", label: "PDF 파일" }, { value: ".doc,.docx", label: "Word 문서" }, { value: ".xls,.xlsx", label: "Excel 파일" }, { value: ".ppt,.pptx", label: "PowerPoint 파일" }, { value: ".txt", label: "텍스트 파일" }, { value: ".zip,.rar", label: "압축 파일" }, { value: ".dwg,.dxf", label: "CAD 파일" }, ]; // 파일 타입 추가 const addAcceptType = useCallback(() => { const newType = localInputs.newAcceptType.trim(); if (newType && !acceptTypes.includes(newType)) { const newAcceptTypes = [...acceptTypes, newType]; setAcceptTypes(newAcceptTypes); onUpdateProperty(component.id, "fileConfig.accept", newAcceptTypes); setLocalInputs((prev) => ({ ...prev, newAcceptType: "" })); } }, [localInputs.newAcceptType, acceptTypes, component.id, onUpdateProperty]); // 파일 타입 제거 const removeAcceptType = useCallback( (typeToRemove: string) => { const newAcceptTypes = acceptTypes.filter((type) => type !== typeToRemove); setAcceptTypes(newAcceptTypes); onUpdateProperty(component.id, "fileConfig.accept", newAcceptTypes); }, [acceptTypes, component.id, onUpdateProperty], ); // 미리 정의된 파일 타입 추가 const addCommonFileType = useCallback( (fileType: string) => { const types = fileType.split(","); const newAcceptTypes = [...acceptTypes]; types.forEach((type) => { if (!newAcceptTypes.includes(type.trim())) { newAcceptTypes.push(type.trim()); } }); setAcceptTypes(newAcceptTypes); onUpdateProperty(component.id, "fileConfig.accept", newAcceptTypes); }, [acceptTypes, component.id, onUpdateProperty], ); return (
{/* 문서 분류 설정 */}

문서 분류 설정

{ const newValue = e.target.value; setLocalInputs((prev) => ({ ...prev, docTypeName: newValue })); onUpdateProperty(component.id, "fileConfig.docTypeName", newValue); }} placeholder="문서 타입 표시명" />
{/* 파일 업로드 제한 설정 */}

파일 업로드 제한

{ const newValue = parseInt(e.target.value) || 10; setLocalInputs((prev) => ({ ...prev, maxSize: newValue })); onUpdateProperty(component.id, "fileConfig.maxSize", newValue); }} />
{ const newValue = parseInt(e.target.value) || 5; setLocalInputs((prev) => ({ ...prev, maxFiles: newValue })); onUpdateProperty(component.id, "fileConfig.maxFiles", newValue); }} />
{ setLocalValues((prev) => ({ ...prev, multiple: checked as boolean })); onUpdateProperty(component.id, "fileConfig.multiple", checked); }} />
{/* 허용 파일 타입 설정 */}

허용 파일 타입

{/* 미리 정의된 파일 타입 버튼들 */}
{commonFileTypes.map((fileType) => ( ))}
{/* 현재 설정된 파일 타입들 */}
{acceptTypes.map((type, index) => ( {type} ))} {acceptTypes.length === 0 && 모든 파일 타입 허용}
{/* 사용자 정의 파일 타입 추가 */}
{ setLocalInputs((prev) => ({ ...prev, newAcceptType: e.target.value })); }} placeholder="예: .dwg, image/*, .custom" onKeyPress={(e) => { if (e.key === "Enter") { addAcceptType(); } }} />
{/* UI 설정 */}

UI 설정