"use client"; import React, { useState, useEffect } from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Button } from "@/components/ui/button"; import { Check, ChevronsUpDown, Search } from "lucide-react"; import { cn } from "@/lib/utils"; import { ComponentData } from "@/types/screen"; import { apiClient } from "@/lib/api/client"; import { ButtonDataflowConfigPanel } from "./ButtonDataflowConfigPanel"; import { ImprovedButtonControlConfigPanel } from "./ImprovedButtonControlConfigPanel"; interface ButtonConfigPanelProps { component: ComponentData; onUpdateProperty: (path: string, value: any) => void; } interface ScreenOption { id: number; name: string; description?: string; } export const ButtonConfigPanel: React.FC = ({ component, onUpdateProperty }) => { // ๐Ÿ”ง ํ•ญ์ƒ ์ตœ์‹  component์—์„œ ์ง์ ‘ ์ฐธ์กฐ const config = component.componentConfig || {}; const currentAction = component.componentConfig?.action || {}; // ๐Ÿ”ง ์ตœ์‹  action ์ฐธ์กฐ // ๋กœ์ปฌ ์ƒํƒœ ๊ด€๋ฆฌ (์‹ค์‹œ๊ฐ„ ์ž…๋ ฅ ๋ฐ˜์˜) const [localInputs, setLocalInputs] = useState({ text: config.text !== undefined ? 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 || "md", // ๐Ÿ”ง ๊ธฐ๋ณธ๊ฐ’์„ "md"๋กœ ๋ณ€๊ฒฝ actionType: config.action?.type, // ๐Ÿ”ง ๊ธฐ๋ณธ๊ฐ’ ์™„์ „ ์ œ๊ฑฐ (undefined) modalSize: config.action?.modalSize || "md", editMode: config.action?.editMode || "modal", }); const [screens, setScreens] = useState([]); const [screensLoading, setScreensLoading] = useState(false); const [modalScreenOpen, setModalScreenOpen] = useState(false); const [navScreenOpen, setNavScreenOpen] = useState(false); const [modalSearchTerm, setModalSearchTerm] = useState(""); const [navSearchTerm, setNavSearchTerm] = useState(""); // ์ปดํฌ๋„ŒํŠธ ๋ณ€๊ฒฝ ์‹œ ๋กœ์ปฌ ์ƒํƒœ ๋™๊ธฐํ™” useEffect(() => { console.log("๐Ÿ”„ ButtonConfigPanel useEffect ์‹คํ–‰:", { componentId: component.id, "config.action?.type": config.action?.type, "localSelects.actionType (before)": localSelects.actionType, fullAction: config.action, "component.componentConfig.action": component.componentConfig?.action, }); setLocalInputs({ text: config.text !== undefined ? config.text : "๋ฒ„ํŠผ", // ๐Ÿ”ง ๋นˆ ๋ฌธ์ž์—ด ํ—ˆ์šฉ modalTitle: config.action?.modalTitle || "", editModalTitle: config.action?.editModalTitle || "", editModalDescription: config.action?.editModalDescription || "", targetUrl: config.action?.targetUrl || "", }); setLocalSelects((prev) => { const newSelects = { variant: config.variant || "default", size: config.size || "md", // ๐Ÿ”ง ๊ธฐ๋ณธ๊ฐ’์„ "md"๋กœ ๋ณ€๊ฒฝ actionType: config.action?.type, // ๐Ÿ”ง ๊ธฐ๋ณธ๊ฐ’ ์™„์ „ ์ œ๊ฑฐ (undefined) modalSize: config.action?.modalSize || "md", editMode: config.action?.editMode || "modal", }; console.log("๐Ÿ“ setLocalSelects ํ˜ธ์ถœ:", { "prev.actionType": prev.actionType, "new.actionType": newSelects.actionType, "config.action?.type": config.action?.type, }); return newSelects; }); }, [ component.id, // ๐Ÿ”ง ์ปดํฌ๋„ŒํŠธ ID (๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „ํ™˜ ์‹œ) component.componentConfig?.action?.type, // ๐Ÿ”ง ์•ก์…˜ ํƒ€์ž… (์•ก์…˜ ๋ณ€๊ฒฝ ์‹œ ์ฆ‰์‹œ ๋ฐ˜์˜) component.componentConfig?.text, // ๐Ÿ”ง ๋ฒ„ํŠผ ํ…์ŠคํŠธ component.componentConfig?.variant, // ๐Ÿ”ง ๋ฒ„ํŠผ ์Šคํƒ€์ผ component.componentConfig?.size, // ๐Ÿ”ง ๋ฒ„ํŠผ ํฌ๊ธฐ ]); // ํ™”๋ฉด ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ useEffect(() => { const fetchScreens = async () => { try { setScreensLoading(true); const response = await apiClient.get("/screen-management/screens"); if (response.data.success && Array.isArray(response.data.data)) { const screenList = response.data.data.map((screen: any) => ({ id: screen.screenId, name: screen.screenName, description: screen.description, })); setScreens(screenList); } } catch (error) { // console.error("โŒ ํ™”๋ฉด ๋ชฉ๋ก ๋กœ๋”ฉ ์‹คํŒจ:", error); } finally { setScreensLoading(false); } }; fetchScreens(); }, []); // ๊ฒ€์ƒ‰ ํ•„ํ„ฐ๋ง ํ•จ์ˆ˜ const filterScreens = (searchTerm: string) => { if (!searchTerm.trim()) return screens; return screens.filter( (screen) => screen.name.toLowerCase().includes(searchTerm.toLowerCase()) || (screen.description && screen.description.toLowerCase().includes(searchTerm.toLowerCase())), ); }; console.log("๐Ÿ”ง config-panels/ButtonConfigPanel ๋ Œ๋”๋ง:", { component, config, action: config.action, actionType: config.action?.type, screensCount: screens.length, }); return (
{ const newValue = e.target.value; setLocalInputs((prev) => ({ ...prev, text: newValue })); onUpdateProperty("componentConfig.text", newValue); }} placeholder="๋ฒ„ํŠผ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”" />
{/* ๋ชจ๋‹ฌ ์—ด๊ธฐ ์•ก์…˜ ์„ค์ • */} {localSelects.actionType === "modal" && (

๋ชจ๋‹ฌ ์„ค์ •

{ const newValue = e.target.value; setLocalInputs((prev) => ({ ...prev, modalTitle: newValue })); onUpdateProperty("componentConfig.action.modalTitle", newValue); }} />
setModalSearchTerm(e.target.value)} className="border-0 p-0 focus-visible:ring-0" />
{(() => { const filteredScreens = filterScreens(modalSearchTerm); if (screensLoading) { return
ํ™”๋ฉด ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...
; } if (filteredScreens.length === 0) { return
๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
; } return filteredScreens.map((screen, index) => (
{ onUpdateProperty("componentConfig.action.targetScreenId", screen.id); setModalScreenOpen(false); setModalSearchTerm(""); }} >
{screen.name} {screen.description && {screen.description}}
)); })()}
)} {/* ์ˆ˜์ • ์•ก์…˜ ์„ค์ • */} {localSelects.actionType === "edit" && (

์ˆ˜์ • ์„ค์ •

setModalSearchTerm(e.target.value)} className="border-0 p-0 focus-visible:ring-0" />
{(() => { const filteredScreens = filterScreens(modalSearchTerm); if (screensLoading) { return
ํ™”๋ฉด ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...
; } if (filteredScreens.length === 0) { return
๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
; } return filteredScreens.map((screen, index) => (
{ onUpdateProperty("componentConfig.action.targetScreenId", screen.id); setModalScreenOpen(false); setModalSearchTerm(""); }} > {screen.name}
)); })()}
)} {/* ๋ณต์‚ฌ ์•ก์…˜ ์„ค์ • */} {localSelects.actionType === "copy" && (

๋ณต์‚ฌ ์„ค์ • (ํ’ˆ๋ชฉ์ฝ”๋“œ ์ž๋™ ์ดˆ๊ธฐํ™”)

setModalSearchTerm(e.target.value)} className="border-0 p-0 focus-visible:ring-0" />
{(() => { const filteredScreens = filterScreens(modalSearchTerm); if (screensLoading) { return
ํ™”๋ฉด ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...
; } if (filteredScreens.length === 0) { return
๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
; } return filteredScreens.map((screen, index) => (
{ onUpdateProperty("componentConfig.action.targetScreenId", screen.id); setModalScreenOpen(false); setModalSearchTerm(""); }} >
{screen.name} {screen.description && {screen.description}}
)); })()}

์„ ํƒ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณต์‚ฌ๋˜๋ฉฐ, ํ’ˆ๋ชฉ์ฝ”๋“œ๋Š” ์ž๋™์œผ๋กœ ์ดˆ๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค

{localSelects.editMode === "modal" && ( <>
{ const newValue = e.target.value; setLocalInputs((prev) => ({ ...prev, editModalTitle: newValue })); onUpdateProperty("componentConfig.action.editModalTitle", newValue); onUpdateProperty("webTypeConfig.editModalTitle", newValue); }} />

๋น„์›Œ๋‘๋ฉด ๊ธฐ๋ณธ ์ œ๋ชฉ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค

{ const newValue = e.target.value; setLocalInputs((prev) => ({ ...prev, editModalDescription: newValue })); onUpdateProperty("componentConfig.action.editModalDescription", newValue); onUpdateProperty("webTypeConfig.editModalDescription", newValue); }} />

๋น„์›Œ๋‘๋ฉด ์„ค๋ช…์ด ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค

)}
)} {/* ํŽ˜์ด์ง€ ์ด๋™ ์•ก์…˜ ์„ค์ • */} {localSelects.actionType === "navigate" && (

ํŽ˜์ด์ง€ ์ด๋™ ์„ค์ •

setNavSearchTerm(e.target.value)} className="border-0 p-0 focus-visible:ring-0" />
{(() => { const filteredScreens = filterScreens(navSearchTerm); if (screensLoading) { return
ํ™”๋ฉด ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...
; } if (filteredScreens.length === 0) { return
๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
; } return filteredScreens.map((screen, index) => (
{ onUpdateProperty("componentConfig.action.targetScreenId", screen.id); setNavScreenOpen(false); setNavSearchTerm(""); }} >
{screen.name} {screen.description && {screen.description}}
)); })()}

์„ ํƒํ•œ ํ™”๋ฉด์œผ๋กœ /screens/{"{"}ํ™”๋ฉดID{"}"} ํ˜•ํƒœ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค

{ const newValue = e.target.value; setLocalInputs((prev) => ({ ...prev, targetUrl: newValue })); onUpdateProperty("componentConfig.action.targetUrl", newValue); }} />

URL์„ ์ž…๋ ฅํ•˜๋ฉด ํ™”๋ฉด ์„ ํƒ๋ณด๋‹ค ์šฐ์„  ์ ์šฉ๋ฉ๋‹ˆ๋‹ค

)} {/* ๐Ÿ”ฅ NEW: ์ œ์–ด๊ด€๋ฆฌ ๊ธฐ๋Šฅ ์„น์…˜ */}

๐Ÿ”ง ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ

๋ฒ„ํŠผ ์•ก์…˜๊ณผ ํ•จ๊ป˜ ์‹คํ–‰๋  ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค

); };