"use client" import { useState } from "react" import { PanelLeft, PanelRight, PanelBottom, File, Folder, Settings, Save, FolderOpen, ImageIcon, Music, Users, } from "lucide-react" import { type Node, NodeType } from "@/types/node" import type { MenuItem } from "@/types/menu" import { TreeNode } from "@/components/tree-node" import { ResizablePanel } from "@/components/resizable-panel" import { HamburgerMenu } from "@/components/hamburger-menu" import { useCanvasAnimation } from "@/hooks/use-canvas-animation" import { Button } from "@/components/ui/button" import { Separator } from "@/components/ui/separator" // Animation duration constant const PANEL_TRANSITION_DURATION = "300ms" // Mock menu data const mockMenuItems: MenuItem[] = [ { id: "file", label: "File", icon: , isExpanded: false, children: [ { id: "new", label: "New Project", icon: , onClick: () => console.log("New Project clicked"), }, { id: "open", label: "Open Project", icon: , onClick: () => console.log("Open Project clicked"), }, { id: "save", label: "Save Project", icon: , onClick: () => console.log("Save Project clicked"), isChecked: true, }, { id: "recent", label: "Recent Files", icon: , isExpanded: false, children: [ { id: "recent1", label: "Project Alpha.vnp", onClick: () => console.log("Recent 1 clicked"), }, { id: "recent2", label: "Story Beta.vnp", onClick: () => console.log("Recent 2 clicked"), }, { id: "recent3", label: "Demo Game.vnp", onClick: () => console.log("Recent 3 clicked"), disabled: true, }, ], }, ], }, { id: "assets", label: "Assets", icon: , isExpanded: true, children: [ { id: "images", label: "Images", icon: , onClick: () => console.log("Images clicked"), }, { id: "audio", label: "Audio", icon: , isExpanded: false, children: [ { id: "music", label: "Background Music", onClick: () => console.log("Music clicked"), }, { id: "sfx", label: "Sound Effects", onClick: () => console.log("SFX clicked"), }, ], }, { id: "characters", label: "Characters", icon: , onClick: () => console.log("Characters clicked"), }, ], }, { id: "tools", label: "Tools", icon: , children: [ { id: "preferences", label: "Preferences", onClick: () => console.log("Preferences clicked"), }, { id: "export", label: "Export Game", onClick: () => console.log("Export clicked"), }, ], }, { id: "layout", label: "Layout", icon: , isExpanded: true, children: [ { id: "center-only-bottom", label: "Bottom panel under center only", isChecked: false, onClick: () => console.log("Center-only bottom panel toggled"), }, ], }, { id: "hidden-item", label: "This should be hidden", isVisible: false, onClick: () => console.log("Hidden clicked"), }, ] // Mock data (same as before) const mockTree: Node = { id: "root", type: NodeType.Episode, actions: [ { name: "Play", imageUrl: "/placeholder.svg?height=24&width=24", description: "Play this episode", onClick: () => console.log("Play clicked"), }, { name: "Edit", imageUrl: "/placeholder.svg?height=24&width=24", description: "Edit this episode", onClick: () => console.log("Edit clicked"), }, ], properties: { title: { id: "title", label: "Title", type: "string", value: "Episode 1", }, duration: { id: "duration", label: "Duration", type: "number", value: 120, readOnly: true, }, }, children: [ { id: "scene1", type: NodeType.Scene, actions: [ { name: "Preview", imageUrl: "/placeholder.svg?height=24&width=24", description: "Preview this scene", onClick: () => console.log("Preview clicked"), }, ], properties: { name: { id: "name", label: "Scene Name", type: "string", value: "Opening Scene", }, }, children: [ { id: "dialogue1", type: NodeType.Dialogue, actions: [], properties: { text: { id: "text", label: "Dialogue Text", type: "string", value: "Hello, welcome to our story!", }, character: { id: "character", label: "Character", type: "string", value: "Narrator", }, }, }, { id: "image1", type: NodeType.Image, actions: [ { name: "Delete", imageUrl: "/placeholder.svg?height=24&width=24", description: "Delete this image", onClick: () => console.log("Delete clicked"), }, ], properties: { src: { id: "src", label: "Image Source", type: "string", value: "/images/background.jpg", }, }, }, ], }, ], } export default function VisualNovelEditor() { const [leftPanelVisible, setLeftPanelVisible] = useState(true) const [rightPanelVisible, setRightPanelVisible] = useState(true) const [bottomPanelVisible, setBottomPanelVisible] = useState(true) const [leftPanelWidth, setLeftPanelWidth] = useState(300) const [rightPanelWidth, setRightPanelWidth] = useState(300) const [bottomPanelHeight, setBottomPanelHeight] = useState(200) const [centerOnlyBottomPanel, setCenterOnlyBottomPanel] = useState(false) // Track when panels are transitioning to enable/disable transitions const [leftPanelTransitioning, setLeftPanelTransitioning] = useState(false) const [rightPanelTransitioning, setRightPanelTransitioning] = useState(false) const [bottomPanelTransitioning, setBottomPanelTransitioning] = useState(false) const [selectedNode, setSelectedNode] = useState(null) const [selectedPath, setSelectedPath] = useState([]) const [expandedNodes, setExpandedNodes] = useState>(new Set(["root", "scene1"])) // Menu state const [menuItems, setMenuItems] = useState(mockMenuItems) const canvasRef = useCanvasAnimation() // Handle panel visibility changes with transition states const toggleLeftPanel = () => { setLeftPanelTransitioning(true) setLeftPanelVisible(!leftPanelVisible) setTimeout(() => setLeftPanelTransitioning(false), 300) } const toggleRightPanel = () => { setRightPanelTransitioning(true) setRightPanelVisible(!rightPanelVisible) setTimeout(() => setRightPanelTransitioning(false), 300) } const toggleBottomPanel = () => { setBottomPanelTransitioning(true) setBottomPanelVisible(!bottomPanelVisible) setTimeout(() => setBottomPanelTransitioning(false), 300) } const handleNodeSelect = (node: Node, path: string[]) => { setSelectedNode(node) setSelectedPath(path) } const toggleExpanded = (nodeId: string) => { const newExpanded = new Set(expandedNodes) if (newExpanded.has(nodeId)) { newExpanded.delete(nodeId) } else { newExpanded.add(nodeId) } setExpandedNodes(newExpanded) } const handleMenuItemClick = (item: MenuItem) => { if (item.id === "center-only-bottom") { setCenterOnlyBottomPanel((current) => !current) setMenuItems((items) => items.map((menuItem) => menuItem.id === "layout" ? { ...menuItem, children: menuItem.children?.map((child) => child.id === "center-only-bottom" ? { ...child, isChecked: !centerOnlyBottomPanel } : child, ), } : menuItem, ), ) return } console.log("Menu item clicked:", item.label) } const handleMenuItemToggle = (itemId: string) => { const updateMenuItems = (items: MenuItem[]): MenuItem[] => { return items.map((item) => { if (item.id === itemId) { return { ...item, isExpanded: !item.isExpanded } } if (item.children) { return { ...item, children: updateMenuItems(item.children) } } return item }) } setMenuItems(updateMenuItems(menuItems)) } const pathString = selectedPath.join(" > ") return (
{/* Main Menu */}

Visual Novel Editor

{/* Main Content Area */}
{/* Top Section - Left, Main, Right Panels */}
{/* Left Panel - Node Tree */}

Node Tree

{/* Main Panel */}
{/* Action Buttons */} {selectedNode && selectedNode.actions.length > 0 && (
{selectedNode.actions.map((action, index) => ( ))}
)} {/* Preview Canvas */}

Preview

{selectedNode ? `Selected: ${pathString}` : "No node selected"}

{/* Right Panel - Info */}

Node Information

{selectedNode ? ( <>

Node Type: {selectedNode.type}

This section contains help information about {selectedNode.type} nodes and how they work within the visual novel engine. Each node type has specific properties and behaviors that affect how the story flows.

Current Path: {pathString}

) : (

Select a node to view information about it.

)}
{/* Bottom Panel - Object Properties */}

{selectedNode?.type || "No Selection"}

{selectedNode ? pathString : "Select a node to view its properties"}

{selectedNode && Object.keys(selectedNode.properties).length > 0 && ( <>
{Object.entries(selectedNode.properties).map(([key, property]) => (
{property.label}: {String(property.value)}
))}
)}
) }