ERP-node/frontend/components/report/designer/ReportDesignerLeftPanel.tsx

109 lines
3.8 KiB
TypeScript

"use client";
import { useState } from "react";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Button } from "@/components/ui/button";
import { ChevronRight, Puzzle, FileText, PanelLeftClose, PanelLeftOpen } from "lucide-react";
import { ComponentPalette } from "./ComponentPalette";
import { TemplatePalette } from "./TemplatePalette";
import { useReportDesigner } from "@/contexts/ReportDesignerContext";
interface AccordionSection {
id: string;
label: string;
icon: React.ReactNode;
}
const SECTIONS: AccordionSection[] = [
{ id: "templates", label: "기본 템플릿", icon: <FileText className="h-5 w-5" /> },
{ id: "components", label: "컴포넌트", icon: <Puzzle className="h-5 w-5" /> },
];
export function ReportDesignerLeftPanel() {
const [expandedSection, setExpandedSection] = useState<string>("components");
const { isLeftPanelCollapsed, setIsLeftPanelCollapsed } = useReportDesigner();
const toggleSection = (id: string) => {
setExpandedSection(expandedSection === id ? "" : id);
};
if (isLeftPanelCollapsed) {
return (
<div className="flex h-full w-10 shrink-0 flex-col items-center border-r border-gray-200 bg-white pt-2 gap-2">
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
onClick={() => setIsLeftPanelCollapsed(false)}
title="도구상자 열기"
>
<PanelLeftOpen className="h-4 w-4" />
</Button>
{SECTIONS.map((section) => (
<Button
key={section.id}
size="icon"
variant="ghost"
className="h-8 w-8"
title={section.label}
onClick={() => {
setIsLeftPanelCollapsed(false);
setExpandedSection(section.id);
}}
>
{section.icon}
</Button>
))}
</div>
);
}
return (
<div className="flex h-full w-[260px] shrink-0 flex-col border-r border-gray-200 bg-white">
<div className="flex h-11 items-center justify-between border-b border-gray-200 px-3">
<span className="text-sm font-bold text-gray-800"></span>
<Button
size="icon"
variant="ghost"
className="h-7 w-7"
onClick={() => setIsLeftPanelCollapsed(true)}
title="도구상자 접기"
>
<PanelLeftClose className="h-4 w-4" />
</Button>
</div>
<ScrollArea className="flex-1">
{SECTIONS.map((section) => {
const isExpanded = expandedSection === section.id;
return (
<div key={section.id} className="border-b-2 border-gray-100">
<button
onClick={() => toggleSection(section.id)}
className={`flex h-14 w-full items-center justify-between px-5 transition-colors ${
isExpanded
? "bg-linear-to-r from-blue-600 to-indigo-600 text-white shadow-sm"
: "bg-white text-gray-900 hover:bg-gray-50"
}`}
>
<div className="flex items-center gap-3">
<span className={isExpanded ? "" : "text-blue-600"}>{section.icon}</span>
<span className="text-base font-bold">{section.label}</span>
</div>
<ChevronRight
className={`h-5 w-5 transition-transform ${isExpanded ? "rotate-90" : "text-gray-400"}`}
/>
</button>
{isExpanded && (
<div className="border-t border-blue-100 bg-linear-to-b from-blue-50/30 to-white p-5">
{section.id === "templates" && <TemplatePalette />}
{section.id === "components" && <ComponentPalette />}
</div>
)}
</div>
);
})}
</ScrollArea>
</div>
);
}