import React, { useCallback, useRef, useEffect } from "react"; import ReactFlow, { Background, Controls, ReactFlowProvider, addEdge, Connection, useReactFlow, applyNodeChanges, applyEdgeChanges, Panel, } from "reactflow"; import { ArrowLeft, Save } from "lucide-react"; import { useFlowStore } from "../store/flowStore"; import { ConfigPanel } from "./ConfigPanel"; import { ComponentsPanel } from "./ComponentsPanel"; import CustomNode from "./CustomNode"; import "reactflow/dist/style.css"; const nodeTypes = { auth: CustomNode, url: CustomNode, output: CustomNode, logic: CustomNode, variable: CustomNode, "db-find": CustomNode, "db-insert": CustomNode, "db-update": CustomNode, "db-delete": CustomNode, "db-query": CustomNode, }; interface FlowEditorContentProps { route: any; onClose: () => void; } function FlowEditorContent({ route, onClose }: FlowEditorContentProps) { const reactFlowWrapper = useRef(null); const { project } = useReactFlow(); const { nodes, edges, setNodes, setEdges, selectedNode, setSelectedNode, updateNodeData, updateRoute, } = useFlowStore(); useEffect(() => { // Load saved flow data if it exists if (route.flowData) { setNodes(route.flowData.nodes); setEdges(route.flowData.edges); } else { // Create default URL node for new routes const defaultNode = { id: `node_${Date.now()}`, type: "url", position: { x: 100, y: 100 }, data: { label: "URL", path: route.url, method: route.method, }, }; setNodes([defaultNode]); setEdges([]); } }, [route, setNodes, setEdges]); const onNodesChange = useCallback( (changes) => setNodes((nds) => applyNodeChanges(changes, nds)), [setNodes] ); const onEdgesChange = useCallback( (changes) => setEdges((eds) => applyEdgeChanges(changes, eds)), [setEdges] ); const onConnect = useCallback( (params: Connection) => setEdges((eds) => addEdge(params, eds)), [setEdges] ); const onDragOver = useCallback((event: React.DragEvent) => { event.preventDefault(); event.dataTransfer.dropEffect = "move"; }, []); const onDrop = useCallback( (event: React.DragEvent) => { event.preventDefault(); const type = event.dataTransfer.getData("application/reactflow"); if (!type || !reactFlowWrapper.current) return; const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect(); const position = project({ x: event.clientX - reactFlowBounds.left - 75, y: event.clientY - reactFlowBounds.top - 25, }); const newNode = { id: `node_${Date.now()}`, type, position, data: { label: type.charAt(0).toUpperCase() + type.slice(1).replace("-", " "), }, }; setNodes((nds) => [...nds, newNode]); }, [project, setNodes] ); const onNodeClick = useCallback( (_: React.MouseEvent, node: any) => { setSelectedNode(node); }, [setSelectedNode] ); const onPaneClick = useCallback(() => { setSelectedNode(null); }, [setSelectedNode]); const handleSave = () => { updateRoute({ ...route, flowData: { nodes, edges, }, }); onClose(); }; return (

{route.name} ({route.method} {route.url})

{selectedNode && ( setSelectedNode(null)} onUpdateNode={updateNodeData} /> )}
); } export function RouteFlowEditor({ route, onClose }: FlowEditorContentProps) { return ( ); }