버튼 액션 수정

This commit is contained in:
kjs 2025-10-21 15:11:15 +09:00
parent e9bd677780
commit 3c0cd6f6dc
1 changed files with 120 additions and 51 deletions

View File

@ -27,6 +27,24 @@ interface ScreenOption {
export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component, onUpdateProperty }) => {
const config = component.componentConfig || {};
// 로컬 상태 관리 (실시간 입력 반영)
const [localInputs, setLocalInputs] = useState({
text: config.text || "버튼",
modalTitle: config.action?.modalTitle || "",
editModalTitle: config.action?.editModalTitle || "",
editModalDescription: config.action?.editModalDescription || "",
targetUrl: config.action?.targetUrl || "",
});
const [localSelects, setLocalSelects] = useState({
variant: config.variant || "default",
size: config.size || "default",
actionType: config.action?.type || "save",
modalSize: config.action?.modalSize || "md",
editMode: config.action?.editMode || "modal",
});
const [screens, setScreens] = useState<ScreenOption[]>([]);
const [screensLoading, setScreensLoading] = useState(false);
const [modalScreenOpen, setModalScreenOpen] = useState(false);
@ -34,6 +52,36 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
const [modalSearchTerm, setModalSearchTerm] = useState("");
const [navSearchTerm, setNavSearchTerm] = useState("");
// 컴포넌트 변경 시 로컬 상태 동기화
useEffect(() => {
setLocalInputs({
text: config.text || "버튼",
modalTitle: config.action?.modalTitle || "",
editModalTitle: config.action?.editModalTitle || "",
editModalDescription: config.action?.editModalDescription || "",
targetUrl: config.action?.targetUrl || "",
});
setLocalSelects({
variant: config.variant || "default",
size: config.size || "default",
actionType: config.action?.type || "save",
modalSize: config.action?.modalSize || "md",
editMode: config.action?.editMode || "modal",
});
}, [
config.text,
config.variant,
config.size,
config.action?.type,
config.action?.modalTitle,
config.action?.modalSize,
config.action?.editMode,
config.action?.editModalTitle,
config.action?.editModalDescription,
config.action?.targetUrl,
]);
// 화면 목록 가져오기
useEffect(() => {
const fetchScreens = async () => {
@ -86,8 +134,12 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<Label htmlFor="button-text"> </Label>
<Input
id="button-text"
value={config.text || "버튼"}
onChange={(e) => onUpdateProperty("componentConfig.text", e.target.value)}
value={localInputs.text}
onChange={(e) => {
const newValue = e.target.value;
setLocalInputs((prev) => ({ ...prev, text: newValue }));
onUpdateProperty("componentConfig.text", newValue);
}}
placeholder="버튼 텍스트를 입력하세요"
/>
</div>
@ -95,8 +147,11 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<div>
<Label htmlFor="button-variant"> </Label>
<Select
value={config.variant || "default"}
onValueChange={(value) => onUpdateProperty("componentConfig.variant", value)}
value={localSelects.variant}
onValueChange={(value) => {
setLocalSelects((prev) => ({ ...prev, variant: value }));
onUpdateProperty("componentConfig.variant", value);
}}
>
<SelectTrigger>
<SelectValue placeholder="버튼 스타일 선택" />
@ -116,8 +171,11 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<div>
<Label htmlFor="button-size"> </Label>
<Select
value={config.size || "default"}
onValueChange={(value) => onUpdateProperty("componentConfig.size", value)}
value={localSelects.size}
onValueChange={(value) => {
setLocalSelects((prev) => ({ ...prev, size: value }));
onUpdateProperty("componentConfig.size", value);
}}
>
<SelectTrigger>
<SelectValue placeholder="버튼 크기 선택" />
@ -133,25 +191,27 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<div>
<Label htmlFor="button-action"> </Label>
<Select
value={config.action?.type || "save"}
defaultValue="save"
value={localSelects.actionType}
onValueChange={(value) => {
// 액션 설정 업데이트
onUpdateProperty("componentConfig.action", { type: value });
// 액션에 따른 라벨 색상 자동 설정
if (value === 'delete') {
console.log("🔵 버튼 액션 변경:", {
oldValue: localSelects.actionType,
newValue: value,
componentId: component.id,
});
// 로컬 상태 업데이트
setLocalSelects((prev) => ({ ...prev, actionType: value }));
// 액션 타입 업데이트
onUpdateProperty("componentConfig.action.type", value);
// 액션에 따른 라벨 색상 자동 설정 (별도 호출)
if (value === "delete") {
// 삭제 액션일 때 빨간색으로 설정
onUpdateProperty("style", {
...component.style,
labelColor: '#ef4444'
});
onUpdateProperty("style.labelColor", "#ef4444");
} else {
// 다른 액션일 때 기본 파란색으로 리셋
onUpdateProperty("style", {
...component.style,
labelColor: '#212121'
});
// 다른 액션일 때 기본색으로 리셋
onUpdateProperty("style.labelColor", "#212121");
}
}}
>
@ -176,7 +236,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
</div>
{/* 모달 열기 액션 설정 */}
{config.action?.type === "modal" && (
{localSelects.actionType === "modal" && (
<div className="mt-4 space-y-4 rounded-lg border bg-gray-50 p-4">
<h4 className="text-sm font-medium text-gray-700"> </h4>
@ -185,26 +245,29 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<Input
id="modal-title"
placeholder="모달 제목을 입력하세요"
value={config.action?.modalTitle || ""}
onChange={(e) =>
value={localInputs.modalTitle}
onChange={(e) => {
const newValue = e.target.value;
setLocalInputs((prev) => ({ ...prev, modalTitle: newValue }));
onUpdateProperty("componentConfig.action", {
...config.action,
modalTitle: e.target.value,
})
}
modalTitle: newValue,
});
}}
/>
</div>
<div>
<Label htmlFor="modal-size"> </Label>
<Select
value={config.action?.modalSize || "md"}
onValueChange={(value) =>
value={localSelects.modalSize}
onValueChange={(value) => {
setLocalSelects((prev) => ({ ...prev, modalSize: value }));
onUpdateProperty("componentConfig.action", {
...config.action,
modalSize: value,
})
}
});
}}
>
<SelectTrigger>
<SelectValue placeholder="모달 크기 선택" />
@ -293,7 +356,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
)}
{/* 수정 액션 설정 */}
{config.action?.type === "edit" && (
{localSelects.actionType === "edit" && (
<div className="mt-4 space-y-4 rounded-lg border bg-green-50 p-4">
<h4 className="text-sm font-medium text-gray-700"> </h4>
@ -375,13 +438,14 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<div>
<Label htmlFor="edit-mode"> </Label>
<Select
value={config.action?.editMode || "modal"}
onValueChange={(value) =>
value={localSelects.editMode}
onValueChange={(value) => {
setLocalSelects((prev) => ({ ...prev, editMode: value }));
onUpdateProperty("componentConfig.action", {
...config.action,
editMode: value,
})
}
});
}}
>
<SelectTrigger>
<SelectValue placeholder="수정 모드 선택" />
@ -394,16 +458,17 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
</Select>
</div>
{config.action?.editMode === "modal" && (
{localSelects.editMode === "modal" && (
<>
<div>
<Label htmlFor="edit-modal-title"> </Label>
<Input
id="edit-modal-title"
placeholder="모달 제목을 입력하세요 (예: 데이터 수정)"
value={config.action?.editModalTitle || ""}
value={localInputs.editModalTitle}
onChange={(e) => {
const newValue = e.target.value;
setLocalInputs((prev) => ({ ...prev, editModalTitle: newValue }));
onUpdateProperty("componentConfig.action", {
...config.action,
editModalTitle: newValue,
@ -420,9 +485,10 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<Input
id="edit-modal-description"
placeholder="모달 설명을 입력하세요 (예: 선택한 데이터를 수정합니다)"
value={config.action?.editModalDescription || ""}
value={localInputs.editModalDescription}
onChange={(e) => {
const newValue = e.target.value;
setLocalInputs((prev) => ({ ...prev, editModalDescription: newValue }));
onUpdateProperty("componentConfig.action", {
...config.action,
editModalDescription: newValue,
@ -437,13 +503,14 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<div>
<Label htmlFor="edit-modal-size"> </Label>
<Select
value={config.action?.modalSize || "lg"}
onValueChange={(value) =>
value={localSelects.modalSize}
onValueChange={(value) => {
setLocalSelects((prev) => ({ ...prev, modalSize: value }));
onUpdateProperty("componentConfig.action", {
...config.action,
modalSize: value,
})
}
});
}}
>
<SelectTrigger>
<SelectValue placeholder="모달 크기 선택" />
@ -463,7 +530,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
)}
{/* 페이지 이동 액션 설정 */}
{config.action?.type === "navigate" && (
{localSelects.actionType === "navigate" && (
<div className="mt-4 space-y-4 rounded-lg border bg-gray-50 p-4">
<h4 className="text-sm font-medium text-gray-700"> </h4>
@ -547,13 +614,15 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<Input
id="target-url"
placeholder="예: /admin/users 또는 https://example.com"
value={config.action?.targetUrl || ""}
onChange={(e) =>
value={localInputs.targetUrl}
onChange={(e) => {
const newValue = e.target.value;
setLocalInputs((prev) => ({ ...prev, targetUrl: newValue }));
onUpdateProperty("componentConfig.action", {
...config.action,
targetUrl: e.target.value,
})
}
targetUrl: newValue,
});
}}
/>
<p className="mt-1 text-xs text-gray-500">URL을 </p>
</div>
@ -564,7 +633,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({ component,
<div className="mt-8 border-t border-gray-200 pt-6">
<div className="mb-4">
<h3 className="text-lg font-medium text-gray-900">🔧 </h3>
<p className="mt-1 text-sm text-muted-foreground"> </p>
<p className="text-muted-foreground mt-1 text-sm"> </p>
</div>
<ImprovedButtonControlConfigPanel component={component} onUpdateProperty={onUpdateProperty} />