Compare commits

..

No commits in common. "ec4d8f9b945187c1a06d69fc7d70fd2a4c5193de" and "a292188ffc4ef8e5162254ba1c47cab5e9bcb636" have entirely different histories.

1 changed files with 51 additions and 120 deletions

View File

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