"use client"; import { useState, useCallback, useEffect } from "react"; export interface PanelState { isOpen: boolean; position: { x: number; y: number }; size: { width: number; height: number }; } export interface PanelConfig { id: string; title: string; defaultPosition: "left" | "right" | "top" | "bottom"; defaultWidth: number; defaultHeight: number; shortcutKey?: string; } export const usePanelState = (panels: PanelConfig[]) => { const [panelStates, setPanelStates] = useState>(() => { const initialStates: Record = {}; panels.forEach((panel) => { initialStates[panel.id] = { isOpen: false, position: { x: 0, y: 0 }, size: { width: panel.defaultWidth, height: panel.defaultHeight }, }; }); return initialStates; }); // 패널 설정이 변경되었을 때 크기 업데이트 useEffect(() => { setPanelStates((prev) => { const newStates = { ...prev }; panels.forEach((panel) => { if (newStates[panel.id]) { // 기존 패널의 위치는 유지하고 크기만 업데이트 newStates[panel.id] = { ...newStates[panel.id], size: { width: panel.defaultWidth, height: panel.defaultHeight }, }; } else { // 새로운 패널이면 전체 초기화 newStates[panel.id] = { isOpen: false, position: { x: 0, y: 0 }, size: { width: panel.defaultWidth, height: panel.defaultHeight }, }; } }); return newStates; }); }, [panels]); // 패널 토글 const togglePanel = useCallback((panelId: string) => { setPanelStates((prev) => ({ ...prev, [panelId]: { ...prev[panelId], isOpen: !prev[panelId]?.isOpen, }, })); }, []); // 패널 열기 const openPanel = useCallback((panelId: string) => { console.log("📂 패널 열기:", { panelId, timestamp: new Date().toISOString(), }); setPanelStates((prev) => ({ ...prev, [panelId]: { ...prev[panelId], isOpen: true, }, })); }, []); // 패널 닫기 const closePanel = useCallback((panelId: string) => { console.log("📁 패널 닫기:", { panelId, timestamp: new Date().toISOString(), }); setPanelStates((prev) => ({ ...prev, [panelId]: { ...prev[panelId], isOpen: false, }, })); }, []); // 모든 패널 닫기 const closeAllPanels = useCallback(() => { setPanelStates((prev) => { const newStates = { ...prev }; Object.keys(newStates).forEach((panelId) => { newStates[panelId] = { ...newStates[panelId], isOpen: false, }; }); return newStates; }); }, []); // 패널 위치 업데이트 const updatePanelPosition = useCallback((panelId: string, position: { x: number; y: number }) => { setPanelStates((prev) => ({ ...prev, [panelId]: { ...prev[panelId], position, }, })); }, []); // 패널 크기 업데이트 const updatePanelSize = useCallback((panelId: string, size: { width: number; height: number }) => { setPanelStates((prev) => ({ ...prev, [panelId]: { ...prev[panelId], size, }, })); }, []); // 키보드 단축키 처리 useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { // Esc 키로 모든 패널 닫기 if (e.key === "Escape") { closeAllPanels(); return; } // 단축키 처리 panels.forEach((panel) => { if (panel.shortcutKey && e.key?.toLowerCase() === panel.shortcutKey?.toLowerCase()) { // Ctrl/Cmd 키와 함께 사용 if (e.ctrlKey || e.metaKey) { e.preventDefault(); togglePanel(panel.id); } } }); }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [panels, togglePanel, closeAllPanels]); return { panelStates, togglePanel, openPanel, closePanel, closeAllPanels, updatePanelPosition, updatePanelSize, }; };