2025-09-10 14:09:32 +09:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import React, { useState } from "react";
|
|
|
|
|
import { ComponentData } from "@/types/screen";
|
|
|
|
|
import { componentRegistry, ComponentRenderer } from "../DynamicComponentRenderer";
|
|
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
|
|
|
|
|
|
|
|
// 접을 수 있는 패널 컴포넌트 렌더러
|
|
|
|
|
const PanelRenderer: ComponentRenderer = ({ component, children, ...props }) => {
|
|
|
|
|
const config = component.componentConfig || {};
|
|
|
|
|
const { title = "패널 제목", collapsible = true, defaultExpanded = true, style = {} } = config;
|
|
|
|
|
|
|
|
|
|
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
|
|
|
|
|
|
|
|
return (
|
2026-03-10 18:30:18 +09:00
|
|
|
<Card
|
|
|
|
|
className="h-full w-full border-2 border-gray-200 shadow-lg transition-all duration-300 hover:border-orange-300 hover:shadow-xl"
|
2025-10-01 16:15:53 +09:00
|
|
|
style={style}
|
|
|
|
|
>
|
2026-03-10 18:30:18 +09:00
|
|
|
<CardHeader className="border-b border-gray-200 bg-gradient-to-r from-slate-50 to-gray-50 pb-2">
|
2025-09-10 14:09:32 +09:00
|
|
|
<div className="flex items-center justify-between">
|
2025-10-01 16:15:53 +09:00
|
|
|
<CardTitle className="text-lg font-semibold text-gray-800">{title}</CardTitle>
|
2025-09-10 14:09:32 +09:00
|
|
|
{collapsible && (
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={() => setIsExpanded(!isExpanded)}
|
2026-03-10 18:30:18 +09:00
|
|
|
className="pointer-events-none h-6 w-6 rounded-full p-0 hover:bg-orange-100"
|
2025-09-10 14:09:32 +09:00
|
|
|
disabled
|
|
|
|
|
>
|
2026-03-10 18:30:18 +09:00
|
|
|
{isExpanded ? (
|
|
|
|
|
<ChevronUp className="h-4 w-4 text-orange-600" />
|
|
|
|
|
) : (
|
|
|
|
|
<ChevronDown className="h-4 w-4 text-orange-600" />
|
|
|
|
|
)}
|
2025-09-10 14:09:32 +09:00
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</CardHeader>
|
|
|
|
|
{isExpanded && (
|
2025-10-01 16:15:53 +09:00
|
|
|
<CardContent className="flex-1 bg-white">
|
2025-09-10 14:09:32 +09:00
|
|
|
{children && React.Children.count(children) > 0 ? (
|
|
|
|
|
children
|
|
|
|
|
) : (
|
2026-03-10 18:30:18 +09:00
|
|
|
<div className="flex h-full items-center justify-center p-8 text-center">
|
|
|
|
|
<div className="rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 p-6">
|
|
|
|
|
<div className="text-sm font-medium text-gray-600">패널 내용 영역</div>
|
2025-10-01 16:15:53 +09:00
|
|
|
<div className="mt-2 text-xs text-gray-400">컴포넌트를 여기에 배치하세요</div>
|
2025-09-10 14:09:32 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</CardContent>
|
|
|
|
|
)}
|
|
|
|
|
</Card>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 레지스트리에 등록
|
|
|
|
|
componentRegistry.register("panel", PanelRenderer);
|
|
|
|
|
componentRegistry.register("panel-collapsible", PanelRenderer);
|
|
|
|
|
|
|
|
|
|
export { PanelRenderer };
|