import { ReactFlowProvider } from '@xyflow/react'; import { InputPanel } from '../components/InputPanel'; import { FlowCanvas } from '../components/FlowCanvas'; import { NodeDetailsPanel } from '../components/NodeDetailsPanel'; import InteractiveLegend from '../components/InteractiveLegend'; import OnboardingTour from '../components/OnboardingTour'; import { useFlowStore } from '../store'; import { useMobileDetect } from '../hooks/useMobileDetect'; import { useState, useCallback, useEffect, useRef } from 'react'; import { PanelLeft, PanelRight, Zap, Sparkles, Minimize2, X } from 'lucide-react'; import { OrchestratorLoader } from '../components/ui/OrchestratorLoader'; import { EditorHeader } from '../components/editor/EditorHeader'; import { VisualOrganizerFAB } from '../components/VisualOrganizerFAB'; import { useDiagramAPI } from '../hooks/useDiagramAPI'; export function Editor() { // Enable Programmatic API useDiagramAPI(); const { nodes, isLoading, leftPanelOpen, setLeftPanelOpen, rightPanelOpen, setRightPanelOpen, focusMode, setFocusMode, mobileEditorOpen, setMobileEditorOpen } = useFlowStore(); const { isMobile } = useMobileDetect(); const [sidebarWidth, setSidebarWidth] = useState(384); // Default w-96 const isResizing = useRef(false); const hasInitializedMobile = useRef(false); // Mobile: Hide panels by default on mount useEffect(() => { if (isMobile && !hasInitializedMobile.current) { setLeftPanelOpen(false); setRightPanelOpen(false); hasInitializedMobile.current = true; } }, [isMobile, setLeftPanelOpen, setRightPanelOpen]); const startResizing = useCallback((e: React.MouseEvent) => { isResizing.current = true; document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', stopResizing); document.body.style.cursor = 'col-resize'; document.body.style.userSelect = 'none'; e.preventDefault(); }, []); const stopResizing = useCallback(() => { isResizing.current = false; document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', stopResizing); document.body.style.cursor = 'default'; document.body.style.userSelect = 'auto'; }, []); const handleMouseMove = useCallback((e: MouseEvent) => { if (!isResizing.current) return; const newWidth = Math.min(Math.max(e.clientX, 300), 700); setSidebarWidth(newWidth); }, []); // Cleanup listeners on unmount useEffect(() => { return () => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', stopResizing); }; }, [handleMouseMove, stopResizing]); return (
{!focusMode && } {/* Exit Focus Mode Trigger */} {focusMode && ( )}
{/* Left Resizable Panel */}
{/* System Architect Header */}
System Architect
{/* Resize Handle */} {leftPanelOpen && (
)}
{(!leftPanelOpen && !focusMode && !isMobile) && ( )} {/* Panoramic Canvas */}
{/* Loading State */} {isLoading && (
)} {/* Empty Workspace - Hidden on mobile (FAB provides access) */} {nodes.length === 0 && !isLoading && !isMobile && (

Void Canvas Ready

Initialize the interface via the terminal or drop a blueprint to begin neural synthesis.

{!leftPanelOpen && ( )}
)} {/* Mobile Empty State - Big Get Started Prompt */} {nodes.length === 0 && !isLoading && isMobile && !mobileEditorOpen && (
{/* Icon */}
{/* Title */}

Create Your Diagram

{/* Description */}

Describe your system in plain English, upload an image, or write Mermaid code.

{/* Get Started Button */} {/* Hint */}

Or tap the button anytime

)}
{/* Right Inspector Panel - Sidebar on desktop, Sheet on mobile */} {!isMobile ? (
Inspector
) : ( rightPanelOpen && !focusMode && (
setRightPanelOpen(false)} />
Inspector
) )} {(nodes.length > 0 && !rightPanelOpen && !focusMode && !isMobile) && ( )}
{/* Mobile FAB - Opens Bottom Sheet */} {isMobile && !mobileEditorOpen && !focusMode && ( <> {/* Visual Organizer FAB (Above Main FAB) */}
)} {/* Mobile Bottom Sheet */} {isMobile && mobileEditorOpen && (
{/* Backdrop */}
setMobileEditorOpen(false)} /> {/* Sheet Content */}
{/* Handle */}
{/* Header */}
System Architect
{/* Content */}
)}
); }