Files
invyone/frontend/components/builder/BuilderLayout.tsx
T
2026-04-10 13:33:37 +09:00

62 lines
2.1 KiB
TypeScript

"use client";
import React, { useEffect, useCallback } from "react";
import { useBuilderState } from "./hooks/useBuilderState";
import BuilderToolbar from "./BuilderToolbar";
import BuilderPalette from "./BuilderPalette";
import BuilderCanvas from "./BuilderCanvas";
import BuilderProps from "./BuilderProps";
import "@/styles/developer.css";
export default function BuilderLayout() {
const blocks = useBuilderState((s) => s.blocks);
const currentView = useBuilderState((s) => s.currentView);
const tableName = useBuilderState((s) => s.tableName);
const connections = useBuilderState((s) => s.connections);
const isDirty = useBuilderState((s) => s.isDirty);
const selectedBlockId = useBuilderState((s) => s.selectedBlockId);
const removeBlock = useBuilderState((s) => s.removeBlock);
const selectBlock = useBuilderState((s) => s.selectBlock);
const viewBlocks = blocks[currentView];
const blockCount = viewBlocks.length;
// 키보드 단축키: Delete/Backspace → 블록 삭제, 화살표 → 블록 이동
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (!selectedBlockId) return;
const tag = (e.target as HTMLElement).tagName;
if (tag === "INPUT" || tag === "SELECT" || tag === "TEXTAREA") return;
if (e.key === "Delete" || e.key === "Backspace") {
e.preventDefault();
removeBlock(selectedBlockId);
}
if (e.key === "Escape") {
selectBlock(null);
}
};
document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler);
}, [selectedBlockId, removeBlock, selectBlock]);
return (
<div className="dev-shell">
<BuilderToolbar />
<div className="dev-body">
<BuilderPalette />
<BuilderCanvas />
<BuilderProps />
</div>
{/* 상태바 */}
<div className="dev-status">
<span> {blockCount} · {tableName || "테이블 미선택"} · {connections.length}</span>
<span>{isDirty ? "수정됨" : "저장됨"}</span>
</div>
</div>
);
}