ERP-node/frontend/components/screen/DesignerToolbar.tsx

258 lines
7.8 KiB
TypeScript

"use client";
import React from "react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
Menu,
Database,
Settings,
Palette,
Grid3X3,
Save,
Undo,
Redo,
ArrowLeft,
Cog,
Layout,
Monitor,
Square,
Languages,
} from "lucide-react";
import { cn } from "@/lib/utils";
interface DesignerToolbarProps {
screenName?: string;
tableName?: string;
onBack: () => void;
onSave: () => void;
onUndo: () => void;
onRedo: () => void;
onTogglePanel: (panelId: string) => void;
panelStates: Record<string, { isOpen: boolean }>;
canUndo: boolean;
canRedo: boolean;
isSaving?: boolean;
showZoneBorders?: boolean;
onToggleZoneBorders?: () => void;
onGenerateMultilang?: () => void;
isGeneratingMultilang?: boolean;
}
export const DesignerToolbar: React.FC<DesignerToolbarProps> = ({
screenName,
tableName,
onBack,
onSave,
onUndo,
onRedo,
onTogglePanel,
panelStates,
canUndo,
canRedo,
isSaving = false,
showZoneBorders = true,
onToggleZoneBorders,
onGenerateMultilang,
isGeneratingMultilang = false,
}) => {
return (
<div className="flex items-center justify-between border-b border-gray-200 bg-gradient-to-r from-gray-50 to-white px-4 py-3 shadow-sm">
{/* 좌측: 네비게이션 및 화면 정보 */}
<div className="flex items-center space-x-4">
<Button variant="ghost" size="sm" onClick={onBack} className="flex items-center space-x-2">
<ArrowLeft className="h-4 w-4" />
<span></span>
</Button>
<div className="h-6 w-px bg-gray-300" />
<div className="flex items-center space-x-3">
<Menu className="h-5 w-5 text-muted-foreground" />
<div>
<h1 className="text-lg font-semibold text-gray-900">{screenName || "화면 설계"}</h1>
{tableName && (
<div className="mt-0.5 flex items-center space-x-1">
<Database className="h-3 w-3 text-gray-500" />
<span className="font-mono text-xs text-gray-500">{tableName}</span>
</div>
)}
</div>
</div>
</div>
{/* 중앙: 패널 토글 버튼들 */}
<div className="flex items-center space-x-2">
<Button
variant={panelStates.tables?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("tables")}
className="flex items-center space-x-2"
>
<Database className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
T
</Badge>
</Button>
<Button
variant={panelStates.templates?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("templates")}
className="flex items-center space-x-2"
>
<Layout className="h-4 w-4" />
<span>릿</span>
<Badge variant="secondary" className="ml-1 text-xs">
M
</Badge>
</Button>
<Button
variant={panelStates.components?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("components")}
className="flex items-center space-x-2"
>
<Cog className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
C
</Badge>
</Button>
<Button
variant={panelStates.properties?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("properties")}
className="flex items-center space-x-2"
>
<Settings className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
P
</Badge>
</Button>
<Button
variant={panelStates.styles?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("styles")}
className="flex items-center space-x-2"
>
<Palette className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
S
</Badge>
</Button>
<Button
variant={panelStates.grid?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("grid")}
className={cn("flex items-center space-x-2", panelStates.grid?.isOpen && "bg-blue-600 text-white")}
>
<Grid3X3 className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
R
</Badge>
</Button>
{/* 구역 경계 표시 토글 버튼 */}
{onToggleZoneBorders && (
<Button
variant={showZoneBorders ? "default" : "outline"}
size="sm"
onClick={onToggleZoneBorders}
className={cn("flex items-center space-x-2", showZoneBorders && "bg-green-600 text-white")}
title="구역 경계 표시/숨김"
>
<Square className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
Z
</Badge>
</Button>
)}
<Button
variant={panelStates.detailSettings?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("detailSettings")}
className={cn("flex items-center space-x-2", panelStates.detailSettings?.isOpen && "bg-blue-600 text-white")}
>
<Cog className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
D
</Badge>
</Button>
<Button
variant={panelStates.resolution?.isOpen ? "default" : "outline"}
size="sm"
onClick={() => onTogglePanel("resolution")}
className={cn("flex items-center space-x-2", panelStates.resolution?.isOpen && "bg-blue-600 text-white")}
>
<Monitor className="h-4 w-4" />
<span></span>
<Badge variant="secondary" className="ml-1 text-xs">
E
</Badge>
</Button>
</div>
{/* 우측: 액션 버튼들 */}
<div className="flex items-center space-x-2">
<Button
variant="outline"
size="sm"
onClick={onUndo}
disabled={!canUndo}
className="flex items-center space-x-1"
>
<Undo className="h-4 w-4" />
<span className="hidden sm:inline"></span>
</Button>
<Button
variant="outline"
size="sm"
onClick={onRedo}
disabled={!canRedo}
className="flex items-center space-x-1"
>
<Redo className="h-4 w-4" />
<span className="hidden sm:inline"></span>
</Button>
<div className="h-6 w-px bg-gray-300" />
{onGenerateMultilang && (
<Button
variant="outline"
size="sm"
onClick={onGenerateMultilang}
disabled={isGeneratingMultilang}
className="flex items-center space-x-1"
title="화면 라벨에 대한 다국어 키를 자동으로 생성합니다"
>
<Languages className="h-4 w-4" />
<span className="hidden sm:inline">{isGeneratingMultilang ? "생성 중..." : "다국어"}</span>
</Button>
)}
<Button onClick={onSave} disabled={isSaving} className="flex items-center space-x-2">
<Save className="h-4 w-4" />
<span>{isSaving ? "저장 중..." : "저장"}</span>
</Button>
</div>
</div>
);
};
export default DesignerToolbar;