'use client' import { useCallback, useState } from 'react' import { ReactFlow, Controls, MiniMap, Background, useNodesState, useEdgesState, addEdge, type Connection, type Node, BackgroundVariant, } from '@xyflow/react' import '@xyflow/react/dist/style.css' import SourceNode from './nodes/SourceNode' import PipeNode from './nodes/PipeNode' import SinkNode from './nodes/SinkNode' import AnimatedPipeEdge from './edges/AnimatedPipeEdge' import FlowToolbar from './FlowToolbar' import { presets } from './presets' const nodeTypes = { source: SourceNode, pipe: PipeNode, sink: SinkNode, } const edgeTypes = { animatedPipe: AnimatedPipeEdge, } export default function FlowCanvas() { const defaultPreset = typeof window !== 'undefined' && window.innerWidth < 768 ? 0 : 0 const [nodes, setNodes, onNodesChange] = useNodesState(presets[defaultPreset].nodes) const [edges, setEdges, onEdgesChange] = useEdgesState(presets[defaultPreset].edges) const [isPlaying, setIsPlaying] = useState(true) const [nodeIdCounter, setNodeIdCounter] = useState(100) const onConnect = useCallback( (connection: Connection) => { setEdges((eds) => addEdge( { ...connection, type: 'animatedPipe', data: { flowRate: 3 } }, eds ) ) }, [setEdges] ) const handleAddNode = useCallback( (type: 'source' | 'pipe' | 'sink') => { const id = `n${nodeIdCounter}` setNodeIdCounter((c) => c + 1) const labels = { source: 'Source', pipe: 'Pipe', sink: 'Sink' } const newNode: Node = { id, type, position: { x: 200 + Math.random() * 200, y: 100 + Math.random() * 200 }, data: { label: labels[type], ...(type === 'source' ? { flowRate: 5 } : {}), ...(type === 'sink' ? { fillLevel: 0 } : {}), }, } setNodes((nds) => [...nds, newNode]) }, [nodeIdCounter, setNodes] ) const handleLoadPreset = useCallback( (index: number) => { const preset = presets[index] setNodes(preset.nodes) setEdges(preset.edges) }, [setNodes, setEdges] ) const handleReset = useCallback(() => { setNodes(presets[2].nodes) setEdges(presets[2].edges) }, [setNodes, setEdges]) const showMiniMap = typeof window !== 'undefined' && window.innerWidth >= 768 return (