2025-09-09 14:29:04 +09:00
|
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
|
|
import React, { useMemo } from "react";
|
|
|
|
|
|
import { WebTypeConfigPanelProps } from "./types";
|
2025-09-09 15:42:04 +09:00
|
|
|
|
import { useWebTypes } from "@/hooks/admin/useWebTypes";
|
|
|
|
|
|
import { getConfigPanelComponent } from "@/lib/utils/getConfigPanelComponent";
|
2025-09-09 14:29:04 +09:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 동적 설정 패널 렌더러 컴포넌트
|
2025-09-09 15:42:04 +09:00
|
|
|
|
* DB에서 웹타입 설정을 조회하여 해당 설정 패널을 동적으로 렌더링합니다.
|
2025-09-09 14:29:04 +09:00
|
|
|
|
*/
|
|
|
|
|
|
export const DynamicConfigPanel: React.FC<
|
|
|
|
|
|
WebTypeConfigPanelProps & {
|
|
|
|
|
|
webType: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
> = ({ webType, component, onUpdateComponent, onUpdateProperty }) => {
|
2025-09-09 15:42:04 +09:00
|
|
|
|
// DB에서 웹타입 목록 조회
|
|
|
|
|
|
const { webTypes } = useWebTypes({ active: "Y" });
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`🔧 DynamicConfigPanel: 웹타입 "${webType}" 설정 패널 로드 시작`);
|
|
|
|
|
|
console.log(`🔧 DynamicConfigPanel: webTypes 로드됨`, webTypes?.length, "개");
|
|
|
|
|
|
|
|
|
|
|
|
// DB에서 웹타입 정보 조회
|
|
|
|
|
|
const dbWebType = useMemo(() => {
|
|
|
|
|
|
if (!webTypes) return null;
|
|
|
|
|
|
const found = webTypes.find((wt) => wt.web_type === webType);
|
|
|
|
|
|
console.log(`🔧 DynamicConfigPanel: 웹타입 "${webType}" DB 조회 결과:`, found);
|
|
|
|
|
|
return found;
|
|
|
|
|
|
}, [webTypes, webType]);
|
|
|
|
|
|
|
|
|
|
|
|
// 웹타입이 DB에 없는 경우
|
|
|
|
|
|
if (!webTypes) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="rounded-md border border-dashed border-gray-300 bg-gray-50 p-4">
|
|
|
|
|
|
<div className="flex items-center gap-2 text-gray-600">
|
|
|
|
|
|
<span className="text-sm font-medium">⏳ 로딩 중...</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p className="mt-1 text-xs text-gray-500">웹타입 정보를 불러오는 중입니다.</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!dbWebType) {
|
|
|
|
|
|
console.warn(`웹타입 "${webType}"이 데이터베이스에 등록되지 않았습니다.`);
|
2025-09-09 14:29:04 +09:00
|
|
|
|
return (
|
|
|
|
|
|
<div className="rounded-md border border-dashed border-red-300 bg-red-50 p-4">
|
|
|
|
|
|
<div className="flex items-center gap-2 text-red-600">
|
2025-09-09 15:42:04 +09:00
|
|
|
|
<span className="text-sm font-medium">⚠️ 웹타입 없음</span>
|
2025-09-09 14:29:04 +09:00
|
|
|
|
</div>
|
2025-09-09 15:42:04 +09:00
|
|
|
|
<p className="mt-1 text-xs text-red-500">웹타입 "{webType}"이 데이터베이스에 등록되지 않았습니다.</p>
|
2025-09-09 14:29:04 +09:00
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-09 15:42:04 +09:00
|
|
|
|
// DB에서 설정 패널 조회
|
|
|
|
|
|
const configPanelName = dbWebType.config_panel;
|
|
|
|
|
|
console.log(`🔧 DynamicConfigPanel: config_panel="${configPanelName}"`);
|
|
|
|
|
|
|
|
|
|
|
|
// 설정 패널이 지정되지 않은 경우
|
|
|
|
|
|
if (!configPanelName || configPanelName === "none") {
|
|
|
|
|
|
console.log(`🔧 DynamicConfigPanel: 설정 패널이 없음 - 기본 설정 표시`);
|
2025-09-09 14:29:04 +09:00
|
|
|
|
return (
|
|
|
|
|
|
<div className="rounded-md border border-dashed border-yellow-300 bg-yellow-50 p-4">
|
|
|
|
|
|
<div className="flex items-center gap-2 text-yellow-600">
|
2025-09-09 15:42:04 +09:00
|
|
|
|
<span className="text-sm font-medium">⚠️ 기본 설정</span>
|
2025-09-09 14:29:04 +09:00
|
|
|
|
</div>
|
2025-09-09 15:42:04 +09:00
|
|
|
|
<p className="mt-1 text-xs text-yellow-500">웹타입 "{webType}"에 대한 추가 설정이 없습니다.</p>
|
2025-09-09 14:29:04 +09:00
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-09 15:42:04 +09:00
|
|
|
|
// 설정 패널 컴포넌트 조회
|
|
|
|
|
|
const ConfigPanelComponent = getConfigPanelComponent(configPanelName);
|
|
|
|
|
|
console.log(`🔧 DynamicConfigPanel: ConfigPanelComponent=`, ConfigPanelComponent);
|
|
|
|
|
|
|
|
|
|
|
|
if (!ConfigPanelComponent) {
|
|
|
|
|
|
console.warn(`설정 패널 "${configPanelName}"을 찾을 수 없습니다.`);
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="rounded-md border border-dashed border-red-300 bg-red-50 p-4">
|
|
|
|
|
|
<div className="flex items-center gap-2 text-red-600">
|
|
|
|
|
|
<span className="text-sm font-medium">⚠️ 설정 패널 미구현</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p className="mt-1 text-xs text-red-500">설정 패널 "{configPanelName}"을 찾을 수 없습니다.</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2025-09-09 14:29:04 +09:00
|
|
|
|
|
|
|
|
|
|
// 설정 패널 props 구성
|
2025-09-09 15:42:04 +09:00
|
|
|
|
const configPanelProps = {
|
|
|
|
|
|
config: component.webTypeConfig || {},
|
|
|
|
|
|
onConfigChange: (newConfig: any) => {
|
|
|
|
|
|
console.log(`🔧 DynamicConfigPanel: 설정 변경`, newConfig);
|
|
|
|
|
|
onUpdateProperty("webTypeConfig", newConfig);
|
|
|
|
|
|
},
|
2025-09-09 14:29:04 +09:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
2025-09-09 15:42:04 +09:00
|
|
|
|
console.log(`🔧 DynamicConfigPanel: "${configPanelName}" 컴포넌트 렌더링 시작`);
|
2025-09-09 14:29:04 +09:00
|
|
|
|
return <ConfigPanelComponent {...configPanelProps} />;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(`웹타입 "${webType}" 설정 패널 렌더링 중 오류 발생:`, error);
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="rounded-md border border-dashed border-red-300 bg-red-50 p-4">
|
|
|
|
|
|
<div className="flex items-center gap-2 text-red-600">
|
|
|
|
|
|
<span className="text-sm font-medium">💥 설정 패널 오류</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p className="mt-1 text-xs text-red-500">웹타입 "{webType}" 설정 패널 렌더링 중 오류가 발생했습니다.</p>
|
|
|
|
|
|
{process.env.NODE_ENV === "development" && (
|
|
|
|
|
|
<pre className="mt-2 overflow-auto text-xs text-red-400">
|
|
|
|
|
|
{error instanceof Error ? error.stack : String(error)}
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
DynamicConfigPanel.displayName = "DynamicConfigPanel";
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 웹타입별 설정 패널을 렌더링하는 헬퍼 함수
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function renderConfigPanel(
|
|
|
|
|
|
webType: string,
|
|
|
|
|
|
component: any,
|
|
|
|
|
|
onUpdateComponent: (component: any) => void,
|
|
|
|
|
|
onUpdateProperty: (property: string, value: any) => void,
|
|
|
|
|
|
): React.ReactElement | null {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<DynamicConfigPanel
|
|
|
|
|
|
webType={webType}
|
|
|
|
|
|
component={component}
|
|
|
|
|
|
onUpdateComponent={onUpdateComponent}
|
|
|
|
|
|
onUpdateProperty={onUpdateProperty}
|
|
|
|
|
|
/>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 웹타입이 설정 패널을 지원하는지 확인하는 헬퍼 함수
|
2025-09-09 15:42:04 +09:00
|
|
|
|
* @deprecated DB 기반 동적 시스템으로 대체됨. DynamicConfigPanel을 직접 사용하세요.
|
2025-09-09 14:29:04 +09:00
|
|
|
|
*/
|
|
|
|
|
|
export function hasConfigPanel(webType: string): boolean {
|
2025-09-09 15:42:04 +09:00
|
|
|
|
console.warn("hasConfigPanel은 deprecated됨. DynamicConfigPanel을 직접 사용하세요.");
|
|
|
|
|
|
return false;
|
2025-09-09 14:29:04 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 웹타입의 기본 설정을 가져오는 헬퍼 함수
|
2025-09-09 15:42:04 +09:00
|
|
|
|
* @deprecated DB 기반 동적 시스템으로 대체됨. 각 설정 패널에서 직접 관리합니다.
|
2025-09-09 14:29:04 +09:00
|
|
|
|
*/
|
|
|
|
|
|
export function getDefaultConfig(webType: string): Record<string, any> | null {
|
2025-09-09 15:42:04 +09:00
|
|
|
|
console.warn("getDefaultConfig는 deprecated됨. 각 설정 패널에서 직접 기본값을 관리하세요.");
|
|
|
|
|
|
return null;
|
2025-09-09 14:29:04 +09:00
|
|
|
|
}
|