"use client"; import { motion, AnimatePresence } from "framer-motion"; import { useState, useEffect } from "react"; import type { Node } from "@xyflow/react"; import VariableReferencePicker from "./VariableReferencePicker"; interface HTTPNodePanelProps { node: Node | null; nodes?: Node[]; onClose: () => void; onDelete: (nodeId: string) => void; onUpdate: (nodeId: string, data: any) => void; } interface Header { key: string; value: string; } export default function HTTPNodePanel({ node, nodes, onClose, onDelete, onUpdate }: HTTPNodePanelProps) { const nodeData = node?.data as any; const [url, setUrl] = useState(nodeData?.httpUrl || "https://api.example.com/endpoint"); const [method, setMethod] = useState(nodeData?.httpMethod || "GET"); const [headers, setHeaders] = useState(nodeData?.httpHeaders || [ { key: "Content-Type", value: "application/json" } ]); const [body, setBody] = useState(nodeData?.httpBody || ""); const [authType, setAuthType] = useState(nodeData?.httpAuthType || "none"); const [authToken, setAuthToken] = useState(nodeData?.httpAuthToken || ""); const [showAuthToken, setShowAuthToken] = useState(false); // Auto-save useEffect(() => { if (!node) return; const timeoutId = setTimeout(() => { onUpdate(node.id, { httpUrl: url, httpMethod: method, httpHeaders: headers, httpBody: body, httpAuthType: authType, httpAuthToken: authToken, }); }, 500); return () => clearTimeout(timeoutId); }, [url, method, headers, body, authType, authToken, node, onUpdate]); const addHeader = () => { setHeaders([...headers, { key: "", value: "" }]); }; const updateHeader = (index: number, field: 'key' | 'value', value: string) => { setHeaders(headers.map((h, i) => i === index ? { ...h, [field]: value } : h)); }; const removeHeader = (index: number) => { setHeaders(headers.filter((_, i) => i !== index)); }; const insertQuickHeader = (key: string, value: string) => { const existing = headers.findIndex(h => h.key === key); if (existing >= 0) { updateHeader(existing, 'value', value); } else { setHeaders([...headers, { key, value }]); } }; return ( {node && ( {/* Header */}

HTTP Request

Call any HTTP/REST API

{/* Form */}
{/* Method and URL */}
setUrl(e.target.value)} placeholder="https://api.example.com/endpoint" className="w-full px-12 py-8 pr-150 bg-background-base border border-border-faint rounded-8 text-body-small text-accent-black font-mono focus:outline-none focus:border-heat-100 transition-colors" /> {nodes && (
setUrl(url + `{{${ref}}}`)} />
)}
{/* Authentication */}
{authType !== 'none' && (
setAuthToken(e.target.value)} placeholder={authType === 'bearer' ? 'Bearer token...' : 'API key or credentials...'} className="w-full px-12 py-8 pr-40 bg-background-base border border-border-faint rounded-8 text-body-small text-accent-black font-mono focus:outline-none focus:border-heat-100 transition-colors" />
)}
{/* Headers */}
{headers.map((header, index) => (
updateHeader(index, 'key', e.target.value)} placeholder="Header-Name" className="flex-1 px-10 py-6 bg-background-base border border-border-faint rounded-6 text-body-small text-accent-black font-mono focus:outline-none focus:border-heat-100 transition-colors" /> updateHeader(index, 'value', e.target.value)} placeholder="value" className="flex-1 px-10 py-6 bg-background-base border border-border-faint rounded-6 text-body-small text-accent-black focus:outline-none focus:border-heat-100 transition-colors" />
))}
{/* Body (for POST/PUT/PATCH) */} {(method === 'POST' || method === 'PUT' || method === 'PATCH') && (
{nodes && ( setBody(body + `{{${ref}}}`)} /> )}