ERP-node/frontend/components/screen/toolbar/LeftV2Toolbar.tsx

87 lines
2.7 KiB
TypeScript
Raw Normal View History

2025-10-15 10:24:33 +09:00
"use client";
import React from "react";
import { Button } from "@/components/ui/button";
import { Layout } from "lucide-react";
2025-10-15 10:24:33 +09:00
import { cn } from "@/lib/utils";
export interface ToolbarButton {
id: string;
label: string;
icon: React.ReactNode;
shortcut: string;
group: "source" | "editor";
panelWidth: number;
}
interface LeftV2ToolbarProps {
2025-10-15 10:24:33 +09:00
buttons: ToolbarButton[];
2025-10-24 15:40:08 +09:00
panelStates: Record<string, { isOpen: boolean; badge?: number }>;
2025-10-15 10:24:33 +09:00
onTogglePanel: (panelId: string) => void;
}
export const LeftV2Toolbar: React.FC<LeftV2ToolbarProps> = ({ buttons, panelStates, onTogglePanel }) => {
2025-10-15 10:24:33 +09:00
// 그룹별로 버튼 분류
const sourceButtons = buttons.filter((btn) => btn.group === "source");
const editorButtons = buttons.filter((btn) => btn.group === "editor");
const renderButton = (button: ToolbarButton) => {
const isActive = panelStates[button.id]?.isOpen || false;
2025-10-24 15:40:08 +09:00
const badge = panelStates[button.id]?.badge;
2025-10-15 10:24:33 +09:00
return (
<Button
key={button.id}
variant="ghost"
onClick={() => onTogglePanel(button.id)}
title={`${button.label} (${button.shortcut})`}
className={cn(
"flex h-14 w-14 flex-col items-center justify-center gap-1 rounded-lg transition-all duration-200",
isActive
? "bg-primary text-primary-foreground shadow-md hover:bg-primary/90"
: "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
2025-10-15 10:24:33 +09:00
)}
>
<div className="relative">
{button.icon}
{isActive && <div className="absolute -top-1 -right-1 h-2 w-2 rounded-full bg-white" />}
2025-10-24 15:40:08 +09:00
{badge !== undefined && badge > 0 && (
<div className="absolute -top-2 -right-2 flex h-5 w-5 items-center justify-center rounded-full bg-destructive text-[10px] font-bold text-white shadow-md">
2025-10-24 15:40:08 +09:00
{badge > 99 ? "99+" : badge}
</div>
)}
2025-10-15 10:24:33 +09:00
</div>
<span className="text-[10px] font-medium">{button.label}</span>
</Button>
);
};
return (
<div className="border-border bg-background flex h-full w-[60px] flex-col border-r">
2025-10-15 10:24:33 +09:00
{/* 입력/소스 그룹 */}
<div className="border-border flex flex-col gap-1 border-b p-1">{sourceButtons.map(renderButton)}</div>
2025-10-15 10:24:33 +09:00
{/* 편집/설정 그룹 */}
<div className="flex flex-col gap-1 p-1">{editorButtons.map(renderButton)}</div>
{/* 하단 여백 */}
<div className="flex-1" />
</div>
);
};
2025-10-28 17:33:03 +09:00
// 기본 버튼 설정 (통합 패널 1개)
2025-10-15 10:24:33 +09:00
export const defaultToolbarButtons: ToolbarButton[] = [
2025-10-28 17:33:03 +09:00
// 통합 패널 (컴포넌트 + 편집 탭)
2025-10-15 10:24:33 +09:00
{
id: "v2",
2025-10-28 17:33:03 +09:00
label: "패널",
2025-10-22 17:19:47 +09:00
icon: <Layout className="h-5 w-5" />,
2025-10-15 10:24:33 +09:00
shortcut: "P",
2025-10-28 17:33:03 +09:00
group: "source",
panelWidth: 240,
2025-10-15 10:24:33 +09:00
},
];
export default LeftV2Toolbar;