"use client"; import React, { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Separator } from "@/components/ui/separator"; import { Badge } from "@/components/ui/badge"; import { Save, X, Trash2, Edit, Plus, RotateCcw, Send, ExternalLink, MousePointer, Settings, AlertTriangle, } from "lucide-react"; import { ButtonActionType, ButtonTypeConfig, WidgetComponent } from "@/types/screen"; interface ButtonConfigPanelProps { component: WidgetComponent; onUpdateComponent: (updates: Partial) => void; } const actionTypeOptions: { value: ButtonActionType; label: string; icon: React.ReactNode; color: string }[] = [ { value: "save", label: "저장", icon: , color: "#3b82f6" }, { value: "cancel", label: "취소", icon: , color: "#6b7280" }, { value: "delete", label: "삭제", icon: , color: "#ef4444" }, { value: "edit", label: "수정", icon: , color: "#f59e0b" }, { value: "add", label: "추가", icon: , color: "#10b981" }, { value: "search", label: "검색", icon: , color: "#8b5cf6" }, { value: "reset", label: "초기화", icon: , color: "#6b7280" }, { value: "submit", label: "제출", icon: , color: "#059669" }, { value: "close", label: "닫기", icon: , color: "#6b7280" }, { value: "popup", label: "팝업 열기", icon: , color: "#8b5cf6" }, { value: "navigate", label: "페이지 이동", icon: , color: "#0ea5e9" }, { value: "custom", label: "사용자 정의", icon: , color: "#64748b" }, ]; export const ButtonConfigPanel: React.FC = ({ component, onUpdateComponent }) => { const config = (component.webTypeConfig as ButtonTypeConfig) || {}; // 로컬 상태 관리 const [localConfig, setLocalConfig] = useState({ actionType: "custom", variant: "default", size: "sm", ...config, }); // 컴포넌트 변경 시 로컬 상태 동기화 useEffect(() => { const newConfig = (component.webTypeConfig as ButtonTypeConfig) || {}; setLocalConfig({ actionType: "custom", variant: "default", size: "sm", ...newConfig, }); }, [component.webTypeConfig]); // 설정 업데이트 함수 const updateConfig = (updates: Partial) => { const newConfig = { ...localConfig, ...updates }; setLocalConfig(newConfig); // 스타일 업데이트도 함께 적용 const styleUpdates: any = {}; if (updates.backgroundColor) styleUpdates.backgroundColor = updates.backgroundColor; if (updates.textColor) styleUpdates.color = updates.textColor; if (updates.borderColor) styleUpdates.borderColor = updates.borderColor; onUpdateComponent({ webTypeConfig: newConfig, ...(Object.keys(styleUpdates).length > 0 && { style: { ...component.style, ...styleUpdates }, }), }); }; // 액션 타입 변경 시 기본값 설정 const handleActionTypeChange = (actionType: ButtonActionType) => { const actionOption = actionTypeOptions.find((opt) => opt.value === actionType); const updates: Partial = { actionType }; // 액션 타입에 따른 기본 설정 switch (actionType) { case "save": updates.variant = "default"; updates.backgroundColor = "#3b82f6"; updates.textColor = "#ffffff"; // 버튼 라벨과 스타일도 업데이트 onUpdateComponent({ label: "저장", style: { ...component.style, backgroundColor: "#3b82f6", color: "#ffffff" }, }); break; case "cancel": case "close": updates.variant = "outline"; updates.backgroundColor = "transparent"; updates.textColor = "#6b7280"; onUpdateComponent({ label: actionType === "cancel" ? "취소" : "닫기", style: { ...component.style, backgroundColor: "transparent", color: "#6b7280", border: "1px solid #d1d5db" }, }); break; case "delete": updates.variant = "destructive"; updates.backgroundColor = "#ef4444"; updates.textColor = "#ffffff"; updates.confirmMessage = "정말로 삭제하시겠습니까?"; onUpdateComponent({ label: "삭제", style: { ...component.style, backgroundColor: "#ef4444", color: "#ffffff" }, }); break; case "edit": updates.backgroundColor = "#f59e0b"; updates.textColor = "#ffffff"; onUpdateComponent({ label: "수정", style: { ...component.style, backgroundColor: "#f59e0b", color: "#ffffff" }, }); break; case "add": updates.backgroundColor = "#10b981"; updates.textColor = "#ffffff"; onUpdateComponent({ label: "추가", style: { ...component.style, backgroundColor: "#10b981", color: "#ffffff" }, }); break; case "search": updates.backgroundColor = "#8b5cf6"; updates.textColor = "#ffffff"; onUpdateComponent({ label: "검색", style: { ...component.style, backgroundColor: "#8b5cf6", color: "#ffffff" }, }); break; case "reset": updates.variant = "outline"; updates.backgroundColor = "transparent"; updates.textColor = "#6b7280"; onUpdateComponent({ label: "초기화", style: { ...component.style, backgroundColor: "transparent", color: "#6b7280", border: "1px solid #d1d5db" }, }); break; case "submit": updates.backgroundColor = "#059669"; updates.textColor = "#ffffff"; onUpdateComponent({ label: "제출", style: { ...component.style, backgroundColor: "#059669", color: "#ffffff" }, }); break; case "popup": updates.backgroundColor = "#8b5cf6"; updates.textColor = "#ffffff"; updates.popupTitle = "상세 정보"; updates.popupContent = "여기에 팝업 내용을 입력하세요."; updates.popupSize = "md"; onUpdateComponent({ label: "상세보기", style: { ...component.style, backgroundColor: "#8b5cf6", color: "#ffffff" }, }); break; case "navigate": updates.backgroundColor = "#0ea5e9"; updates.textColor = "#ffffff"; updates.navigateUrl = "/"; updates.navigateTarget = "_self"; onUpdateComponent({ label: "이동", style: { ...component.style, backgroundColor: "#0ea5e9", color: "#ffffff" }, }); break; case "custom": updates.backgroundColor = "#64748b"; updates.textColor = "#ffffff"; onUpdateComponent({ label: "버튼", style: { ...component.style, backgroundColor: "#64748b", color: "#ffffff" }, }); break; } updateConfig(updates); }; const selectedActionOption = actionTypeOptions.find((opt) => opt.value === localConfig.actionType); return (
버튼 기능 설정 {/* 액션 타입 선택 */}
{selectedActionOption && (
{selectedActionOption.icon} {selectedActionOption.label} {selectedActionOption.value}
)}
{/* 기본 설정 */}
{/* 버튼 텍스트 */}
{ const newValue = e.target.value; onUpdateComponent({ label: newValue }); }} placeholder="버튼에 표시될 텍스트" className="h-8 text-xs" />
{/* 버튼 스타일 */}
{/* 아이콘 설정 */}
updateConfig({ icon: e.target.value })} placeholder="예: Save, Edit, Trash2" className="h-8 text-xs" />
{/* 액션별 세부 설정 */} {localConfig.actionType === "delete" && (
updateConfig({ confirmMessage: e.target.value })} placeholder="정말로 삭제하시겠습니까?" className="h-8 text-xs" />
)} {localConfig.actionType === "popup" && (
updateConfig({ popupTitle: e.target.value })} placeholder="상세 정보" className="h-8 text-xs" />