@webdevarif/reactflow
Version: 
Reusable ReactFlow components for social media bot automation
1,229 lines (1,219 loc) • 50.6 kB
JavaScript
// src/facebook/FacebookWorkflow.tsx
import React6, { useCallback, useState, useRef, useMemo } from "react";
import ReactFlow, {
  addEdge,
  Background,
  Controls,
  MiniMap,
  useNodesState,
  useEdgesState,
  ReactFlowProvider
} from "reactflow";
import "reactflow/dist/style.css";
import { Plus, Settings, Trash2, Play, Save, Download, Upload } from "lucide-react";
// src/facebook/components/MessageNodes.tsx
import { Handle, Position } from "reactflow";
import { jsx, jsxs } from "react/jsx-runtime";
var BaseNode = ({ data, selected }) => {
  const getIcon = (type) => {
    switch (type) {
      case "text":
        return "\u{1F4AC}";
      case "image":
        return "\u{1F5BC}\uFE0F";
      case "audio":
        return "\u{1F3B5}";
      case "video":
        return "\u{1F3A5}";
      case "file":
        return "\u{1F4C4}";
      case "fb_media":
        return "\u{1F4F1}";
      case "carousel":
        return "\u{1F3A0}";
      case "ecommerce":
        return "\u{1F6D2}";
      case "ai_reply":
        return "\u{1F916}";
      default:
        return "\u2699\uFE0F";
    }
  };
  const getColor = (type) => {
    switch (type) {
      case "text":
        return "bg-blue-50 border-blue-200 text-blue-800";
      case "image":
        return "bg-green-50 border-green-200 text-green-800";
      case "audio":
        return "bg-purple-50 border-purple-200 text-purple-800";
      case "video":
        return "bg-red-50 border-red-200 text-red-800";
      case "file":
        return "bg-gray-50 border-gray-200 text-gray-800";
      case "fb_media":
        return "bg-indigo-50 border-indigo-200 text-indigo-800";
      case "carousel":
        return "bg-yellow-50 border-yellow-200 text-yellow-800";
      case "ecommerce":
        return "bg-pink-50 border-pink-200 text-pink-800";
      case "ai_reply":
        return "bg-gradient-to-r from-purple-50 to-pink-50 border-purple-200 text-purple-800";
      default:
        return "bg-gray-50 border-gray-200 text-gray-800";
    }
  };
  return /* @__PURE__ */ jsxs("div", { className: `px-4 py-3 shadow-sm rounded-lg border-2 min-w-[200px] max-w-[250px] ${getColor(data.type)} ${selected ? "ring-2 ring-blue-500 shadow-lg" : "hover:shadow-md"} transition-all duration-200`, children: [
    /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
      /* @__PURE__ */ jsx("span", { className: "text-xl", children: getIcon(data.type) }),
      /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
        /* @__PURE__ */ jsx("div", { className: "font-semibold text-sm truncate", children: data.label }),
        data.content && /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-600 mt-1 line-clamp-2", children: data.content })
      ] })
    ] }),
    data.mediaUrl && /* @__PURE__ */ jsxs("div", { className: "mt-2 text-xs text-gray-500 flex items-center gap-1", children: [
      /* @__PURE__ */ jsx("span", { children: "\u{1F4CE}" }),
      /* @__PURE__ */ jsx("span", { children: data.mediaType || "media" })
    ] }),
    /* @__PURE__ */ jsx(
      Handle,
      {
        type: "target",
        position: Position.Top,
        className: "w-3 h-3 bg-white border-2 border-gray-400 hover:border-blue-500",
        style: { top: -6 }
      }
    ),
    /* @__PURE__ */ jsx(
      Handle,
      {
        type: "source",
        position: Position.Bottom,
        className: "w-3 h-3 bg-white border-2 border-gray-400 hover:border-blue-500",
        style: { bottom: -6 }
      }
    )
  ] });
};
var TextMessageNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var ImageMessageNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var AudioMessageNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var VideoMessageNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var FileMessageNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var FacebookMediaNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var CarouselNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var EcommerceNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var AIReplyNode = (props) => /* @__PURE__ */ jsx(BaseNode, { ...props });
var ConditionNode = ({ data, selected }) => /* @__PURE__ */ jsxs("div", { className: `px-4 py-3 shadow-sm rounded-lg border-2 min-w-[200px] max-w-[250px] bg-orange-50 border-orange-200 text-orange-800 ${selected ? "ring-2 ring-orange-500 shadow-lg" : "hover:shadow-md"} transition-all duration-200`, children: [
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
    /* @__PURE__ */ jsx("span", { className: "text-xl", children: "\u{1F500}" }),
    /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
      /* @__PURE__ */ jsx("div", { className: "font-semibold text-sm truncate", children: data.label }),
      data.metadata?.condition && /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-600 mt-1", children: data.metadata.condition })
    ] })
  ] }),
  /* @__PURE__ */ jsx(
    Handle,
    {
      type: "target",
      position: Position.Top,
      className: "w-3 h-3 bg-white border-2 border-gray-400 hover:border-orange-500",
      style: { top: -6 }
    }
  ),
  /* @__PURE__ */ jsx(
    Handle,
    {
      type: "source",
      position: Position.Bottom,
      className: "w-3 h-3 bg-white border-2 border-gray-400 hover:border-orange-500",
      style: { bottom: -6 }
    }
  )
] });
var DelayNode = ({ data, selected }) => /* @__PURE__ */ jsxs("div", { className: `px-4 py-3 shadow-sm rounded-lg border-2 min-w-[200px] max-w-[250px] bg-cyan-50 border-cyan-200 text-cyan-800 ${selected ? "ring-2 ring-cyan-500 shadow-lg" : "hover:shadow-md"} transition-all duration-200`, children: [
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
    /* @__PURE__ */ jsx("span", { className: "text-xl", children: "\u23F1\uFE0F" }),
    /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
      /* @__PURE__ */ jsx("div", { className: "font-semibold text-sm truncate", children: data.label }),
      data.metadata?.delay && /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-600 mt-1", children: [
        (data.metadata.delay / 1e3).toFixed(1),
        "s"
      ] })
    ] })
  ] }),
  /* @__PURE__ */ jsx(
    Handle,
    {
      type: "target",
      position: Position.Top,
      className: "w-3 h-3 bg-white border-2 border-gray-400 hover:border-cyan-500",
      style: { top: -6 }
    }
  ),
  /* @__PURE__ */ jsx(
    Handle,
    {
      type: "source",
      position: Position.Bottom,
      className: "w-3 h-3 bg-white border-2 border-gray-400 hover:border-cyan-500",
      style: { bottom: -6 }
    }
  )
] });
var TriggerNode = ({ data, selected }) => {
  const getIcon = (type) => {
    switch (type) {
      case "receive_message":
        return "\u{1F4AC}";
      case "receive_comment":
        return "\u{1F4AC}";
      case "receive_post_reaction":
        return "\u{1F44D}";
      case "receive_page_like":
        return "\u2764\uFE0F";
      default:
        return "\u26A1";
    }
  };
  return /* @__PURE__ */ jsxs("div", { className: `px-4 py-3 shadow-sm rounded-lg border-2 min-w-[200px] max-w-[250px] bg-green-50 border-green-200 text-green-800 ${selected ? "ring-2 ring-green-500 shadow-lg" : "hover:shadow-md"} transition-all duration-200`, children: [
    /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
      /* @__PURE__ */ jsx("span", { className: "text-xl", children: getIcon(data.type) }),
      /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
        /* @__PURE__ */ jsx("div", { className: "font-semibold text-sm truncate", children: data.label }),
        data.metadata?.keywords && /* @__PURE__ */ jsxs("div", { className: "text-xs text-green-600 mt-1 font-medium", children: [
          "Keywords: ",
          data.metadata.keywords
        ] })
      ] })
    ] }),
    /* @__PURE__ */ jsx("div", { className: "mt-2 text-xs text-green-600 font-medium", children: "TRIGGER" }),
    /* @__PURE__ */ jsx(
      Handle,
      {
        type: "source",
        position: Position.Bottom,
        className: "w-3 h-3 bg-white border-2 border-gray-400 hover:border-green-500",
        style: { bottom: -6 }
      }
    )
  ] });
};
// src/facebook/config.ts
var facebookNodeTypes = {
  // Trigger nodes
  receive_message: TriggerNode,
  receive_comment: TriggerNode,
  receive_post_reaction: TriggerNode,
  receive_page_like: TriggerNode,
  // Action nodes
  text: TextMessageNode,
  image: ImageMessageNode,
  audio: AudioMessageNode,
  video: VideoMessageNode,
  file: FileMessageNode,
  fb_media: FacebookMediaNode,
  carousel: CarouselNode,
  ecommerce: EcommerceNode,
  ai_reply: AIReplyNode,
  condition: ConditionNode,
  delay: DelayNode
};
var facebookEdgeTypes = {
  default: "smoothstep",
  conditional: "smoothstep"
};
var facebookSupportedMessageTypes = [
  "text",
  "image",
  "audio",
  "video",
  "file",
  "fb_media",
  "carousel",
  "ecommerce",
  "ai_reply"
];
var facebookNodeTemplates = {
  // Trigger nodes
  receive_message: {
    type: "receive_message",
    data: {
      label: "Receive Message",
      type: "trigger",
      metadata: {
        triggerType: "message",
        event: "message_received",
        keywords: "{{ body }}",
        matchType: "contains",
        exactMatch: false
      }
    },
    position: { x: 0, y: 0 }
  },
  receive_comment: {
    type: "receive_comment",
    data: {
      label: "Receive Comment",
      type: "trigger",
      metadata: {
        triggerType: "comment",
        event: "comment_received",
        keywords: "{{ body }}",
        matchType: "contains",
        exactMatch: false
      }
    },
    position: { x: 0, y: 0 }
  },
  receive_post_reaction: {
    type: "receive_post_reaction",
    data: {
      label: "Receive Post Reaction",
      type: "trigger",
      metadata: {
        triggerType: "reaction",
        event: "post_reaction"
      }
    },
    position: { x: 0, y: 0 }
  },
  receive_page_like: {
    type: "receive_page_like",
    data: {
      label: "Receive Page Like",
      type: "trigger",
      metadata: {
        triggerType: "page_like",
        event: "page_liked"
      }
    },
    position: { x: 0, y: 0 }
  },
  // Action nodes
  text: {
    type: "text",
    data: {
      label: "Text Message",
      type: "text",
      content: "Hello! How can I help you today?"
    },
    position: { x: 0, y: 0 }
  },
  image: {
    type: "image",
    data: {
      label: "Image Message",
      type: "image",
      content: "Check out this image!",
      mediaType: "image"
    },
    position: { x: 0, y: 0 }
  },
  audio: {
    type: "audio",
    data: {
      label: "Audio Message",
      type: "audio",
      content: "Listen to this audio",
      mediaType: "audio"
    },
    position: { x: 0, y: 0 }
  },
  video: {
    type: "video",
    data: {
      label: "Video Message",
      type: "video",
      content: "Watch this video",
      mediaType: "video"
    },
    position: { x: 0, y: 0 }
  },
  file: {
    type: "file",
    data: {
      label: "File Message",
      type: "file",
      content: "Here is your file",
      mediaType: "file"
    },
    position: { x: 0, y: 0 }
  },
  fb_media: {
    type: "fb_media",
    data: {
      label: "Facebook Media",
      type: "fb_media",
      content: "Facebook media content",
      mediaType: "image"
    },
    position: { x: 0, y: 0 }
  },
  carousel: {
    type: "carousel",
    data: {
      label: "Carousel",
      type: "carousel",
      content: "Browse our products",
      metadata: {
        items: []
      }
    },
    position: { x: 0, y: 0 }
  },
  ecommerce: {
    type: "ecommerce",
    data: {
      label: "E-commerce",
      type: "ecommerce",
      content: "Shop now",
      metadata: {
        products: []
      }
    },
    position: { x: 0, y: 0 }
  },
  ai_reply: {
    type: "ai_reply",
    data: {
      label: "AI Reply",
      type: "ai_reply",
      content: "AI-powered response",
      metadata: {
        prompt: "",
        model: "gpt-3.5-turbo"
      }
    },
    position: { x: 0, y: 0 }
  },
  condition: {
    type: "condition",
    data: {
      label: "Condition",
      type: "condition",
      metadata: {
        condition: "user_input",
        operator: "contains",
        value: "help"
      }
    },
    position: { x: 0, y: 0 }
  },
  delay: {
    type: "delay",
    data: {
      label: "Delay",
      type: "delay",
      metadata: {
        delay: 300
      }
    },
    position: { x: 0, y: 0 }
  }
};
// src/components/ui/button.tsx
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva } from "class-variance-authority";
// src/lib/utils.ts
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
function cn(...inputs) {
  return twMerge(clsx(inputs));
}
// src/components/ui/button.tsx
import { jsx as jsx2 } from "react/jsx-runtime";
var buttonVariants = cva(
  "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
        secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline"
      },
      size: {
        default: "h-10 px-4 py-2",
        sm: "h-9 rounded-md px-3",
        lg: "h-11 rounded-md px-8",
        icon: "h-10 w-10"
      }
    },
    defaultVariants: {
      variant: "default",
      size: "default"
    }
  }
);
var Button = React.forwardRef(
  ({ className, variant, size, asChild = false, ...props }, ref) => {
    const Comp = asChild ? Slot : "button";
    return /* @__PURE__ */ jsx2(
      Comp,
      {
        className: cn(buttonVariants({ variant, size, className })),
        ref,
        ...props
      }
    );
  }
);
Button.displayName = "Button";
// src/components/ui/input.tsx
import * as React2 from "react";
import { jsx as jsx3 } from "react/jsx-runtime";
var Input = React2.forwardRef(
  ({ className, type, ...props }, ref) => {
    return /* @__PURE__ */ jsx3(
      "input",
      {
        type,
        className: cn(
          "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
          className
        ),
        ref,
        ...props
      }
    );
  }
);
Input.displayName = "Input";
// src/components/ui/select.tsx
import * as React3 from "react";
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown, ChevronUp } from "lucide-react";
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
var Select = SelectPrimitive.Root;
var SelectValue = SelectPrimitive.Value;
var SelectTrigger = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
  SelectPrimitive.Trigger,
  {
    ref,
    className: cn(
      "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
      className
    ),
    ...props,
    children: [
      children,
      /* @__PURE__ */ jsx4(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx4(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
    ]
  }
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
var SelectScrollUpButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(
  SelectPrimitive.ScrollUpButton,
  {
    ref,
    className: cn(
      "flex cursor-default items-center justify-center py-1",
      className
    ),
    ...props,
    children: /* @__PURE__ */ jsx4(ChevronUp, { className: "h-4 w-4" })
  }
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
var SelectScrollDownButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(
  SelectPrimitive.ScrollDownButton,
  {
    ref,
    className: cn(
      "flex cursor-default items-center justify-center py-1",
      className
    ),
    ...props,
    children: /* @__PURE__ */ jsx4(ChevronDown, { className: "h-4 w-4" })
  }
));
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx4(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs2(
  SelectPrimitive.Content,
  {
    ref,
    className: cn(
      "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
      position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
      className
    ),
    position,
    ...props,
    children: [
      /* @__PURE__ */ jsx4(SelectScrollUpButton, {}),
      /* @__PURE__ */ jsx4(
        SelectPrimitive.Viewport,
        {
          className: cn(
            "p-1",
            position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
          ),
          children
        }
      ),
      /* @__PURE__ */ jsx4(SelectScrollDownButton, {})
    ]
  }
) }));
SelectContent.displayName = SelectPrimitive.Content.displayName;
var SelectLabel = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(
  SelectPrimitive.Label,
  {
    ref,
    className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
    ...props
  }
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;
var SelectItem = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
  SelectPrimitive.Item,
  {
    ref,
    className: cn(
      "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
      className
    ),
    ...props,
    children: [
      /* @__PURE__ */ jsx4("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx4(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx4(Check, { className: "h-4 w-4" }) }) }),
      /* @__PURE__ */ jsx4(SelectPrimitive.ItemText, { children })
    ]
  }
));
SelectItem.displayName = SelectPrimitive.Item.displayName;
var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(
  SelectPrimitive.Separator,
  {
    ref,
    className: cn("-mx-1 my-1 h-px bg-muted", className),
    ...props
  }
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
// src/components/ui/switch.tsx
import * as React4 from "react";
import * as SwitchPrimitives from "@radix-ui/react-switch";
import { jsx as jsx5 } from "react/jsx-runtime";
var Switch = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
  SwitchPrimitives.Root,
  {
    className: cn(
      "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
      className
    ),
    ...props,
    ref,
    children: /* @__PURE__ */ jsx5(
      SwitchPrimitives.Thumb,
      {
        className: cn(
          "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
        )
      }
    )
  }
));
Switch.displayName = SwitchPrimitives.Root.displayName;
// src/components/ui/textarea.tsx
import * as React5 from "react";
import { jsx as jsx6 } from "react/jsx-runtime";
var Textarea = React5.forwardRef(
  ({ className, ...props }, ref) => {
    return /* @__PURE__ */ jsx6(
      "textarea",
      {
        className: cn(
          "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
          className
        ),
        ref,
        ...props
      }
    );
  }
);
Textarea.displayName = "Textarea";
// src/facebook/FacebookWorkflow.tsx
import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
var FacebookWorkflow = ({
  initialNodes = [],
  initialEdges = [],
  initialTitle = "Facebook Bot Workflow",
  onSave,
  onNodeClick,
  onEdgeClick,
  onTitleChange,
  className = "",
  height = "600px"
}) => {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
  const [selectedNode, setSelectedNode] = useState(null);
  const [showTriggerPopup, setShowTriggerPopup] = useState(false);
  const [showSidebar, setShowSidebar] = useState(true);
  const [sidebarTab, setSidebarTab] = useState("nodes");
  const [isDragOver, setIsDragOver] = useState(false);
  const [isClient, setIsClient] = useState(false);
  const [forceUpdate, setForceUpdate] = useState(0);
  const [workflowTitle, setWorkflowTitle] = useState(initialTitle);
  const [isEditingTitle, setIsEditingTitle] = useState(false);
  const reactFlowInstance = useRef(null);
  React6.useEffect(() => {
    setIsClient(true);
  }, []);
  const memoizedNodeTypes = useMemo(() => facebookNodeTypes, []);
  const memoizedEdgeTypes = useMemo(() => facebookEdgeTypes, []);
  const forceRerender = useCallback(() => {
    setForceUpdate((prev) => prev + 1);
  }, []);
  const handleTitleChange = useCallback((newTitle) => {
    setWorkflowTitle(newTitle);
    onTitleChange?.(newTitle);
  }, [onTitleChange]);
  const handleTitleSubmit = useCallback(() => {
    setIsEditingTitle(false);
    onTitleChange?.(workflowTitle);
  }, [workflowTitle, onTitleChange]);
  const handleTitleKeyDown = useCallback((e) => {
    if (e.key === "Enter") {
      handleTitleSubmit();
    } else if (e.key === "Escape") {
      setWorkflowTitle(initialTitle);
      setIsEditingTitle(false);
    }
  }, [handleTitleSubmit, initialTitle]);
  const onConnect = useCallback(
    (params) => setEdges((eds) => addEdge(params, eds)),
    [setEdges]
  );
  const handleNodeClick = useCallback((event, node) => {
    setSelectedNode(node);
    setSidebarTab("properties");
    onNodeClick?.(node);
  }, [onNodeClick]);
  const handleEdgeClick = useCallback((event, edge) => {
    onEdgeClick?.(edge);
  }, [onEdgeClick]);
  const addNode = useCallback((nodeType, position) => {
    const template = facebookNodeTemplates[nodeType];
    if (template) {
      const newNode = {
        ...template,
        id: `${nodeType}_${Date.now()}`,
        position: position || {
          x: Math.random() * 400 + 200,
          y: Math.random() * 400 + 200
        }
      };
      setNodes((nds) => [...nds, newNode]);
    }
    setShowTriggerPopup(false);
  }, [setNodes]);
  const onInit = useCallback((instance) => {
    reactFlowInstance.current = instance;
  }, []);
  const onDragOver = useCallback((event) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = "move";
    setIsDragOver(true);
  }, []);
  const onDrop = useCallback((event) => {
    event.preventDefault();
    setIsDragOver(false);
    const nodeType = event.dataTransfer.getData("application/reactflow");
    if (!nodeType || !reactFlowInstance.current) {
      return;
    }
    const position = reactFlowInstance.current.screenToFlowPosition({
      x: event.clientX,
      y: event.clientY
    });
    addNode(nodeType, position);
  }, [addNode]);
  const onDragLeave = useCallback(() => {
    setIsDragOver(false);
  }, []);
  const onDragStart = useCallback((event, nodeType) => {
    event.dataTransfer.setData("application/reactflow", nodeType);
    event.dataTransfer.effectAllowed = "move";
  }, []);
  const deleteNode = useCallback((nodeId) => {
    setNodes((nds) => nds.filter((node) => node.id !== nodeId));
    setEdges((eds) => eds.filter((edge) => edge.source !== nodeId && edge.target !== nodeId));
    setSelectedNode(null);
  }, [setNodes, setEdges]);
  const saveWorkflow = useCallback(() => {
    const config = {
      name: workflowTitle,
      description: "Automated Facebook Messenger bot workflow",
      platform: "facebook",
      nodes,
      edges
    };
    onSave?.(config);
  }, [nodes, edges, workflowTitle, onSave]);
  const nodeGroups = {
    "Triggers": [
      { type: "receive_message", label: "Receive Message", icon: "\u{1F4E8}", description: "Triggered when user sends a message" },
      { type: "receive_comment", label: "Receive Comment", icon: "\u{1F4AC}", description: "Triggered when user comments on post" },
      { type: "receive_post_reaction", label: "Receive Post Reaction", icon: "\u{1F44D}", description: "Triggered when user reacts to post" },
      { type: "receive_page_like", label: "Receive Page Like", icon: "\u2764\uFE0F", description: "Triggered when user likes the page" }
    ],
    "Messages": [
      { type: "text", label: "Text Message", icon: "\u{1F4AC}", description: "Send a text message" },
      { type: "image", label: "Image Message", icon: "\u{1F5BC}\uFE0F", description: "Send an image" },
      { type: "audio", label: "Audio Message", icon: "\u{1F3B5}", description: "Send audio" },
      { type: "video", label: "Video Message", icon: "\u{1F3A5}", description: "Send video" }
    ],
    "Media": [
      { type: "file", label: "File Message", icon: "\u{1F4C4}", description: "Send a file" },
      { type: "fb_media", label: "Facebook Media", icon: "\u{1F4F1}", description: "Facebook media content" },
      { type: "carousel", label: "Carousel", icon: "\u{1F3A0}", description: "Carousel of items" }
    ],
    "Commerce": [
      { type: "ecommerce", label: "E-commerce", icon: "\u{1F6D2}", description: "E-commerce products" }
    ],
    "AI & Logic": [
      { type: "ai_reply", label: "AI Reply", icon: "\u{1F916}", description: "AI-powered response" },
      { type: "condition", label: "Condition", icon: "\u{1F500}", description: "Conditional logic" },
      { type: "delay", label: "Delay", icon: "\u23F1\uFE0F", description: "Add delay" }
    ]
  };
  if (!isClient) {
    return /* @__PURE__ */ jsx7("div", { className: `w-full h-full bg-gray-50 flex items-center justify-center ${className}`, style: { height }, children: /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
      /* @__PURE__ */ jsx7("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4" }),
      /* @__PURE__ */ jsx7("p", { className: "text-gray-600", children: "Loading workflow builder..." })
    ] }) });
  }
  return /* @__PURE__ */ jsxs3("div", { className: `w-full h-full bg-gray-50 flex flex-col ${className}`, style: { height }, children: [
    /* @__PURE__ */ jsxs3("div", { className: "h-14 bg-white border-b border-gray-200 flex items-center justify-between px-4", children: [
      /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-4", children: [
        isEditingTitle ? /* @__PURE__ */ jsx7(
          Input,
          {
            value: workflowTitle,
            onChange: (e) => setWorkflowTitle(e.target.value),
            onBlur: handleTitleSubmit,
            onKeyDown: handleTitleKeyDown,
            className: "text-lg font-semibold text-gray-900 bg-transparent border-none p-0 focus:ring-0 focus:border-none",
            autoFocus: true
          }
        ) : /* @__PURE__ */ jsx7(
          "h1",
          {
            className: "text-lg font-semibold text-gray-900 cursor-pointer hover:bg-gray-100 px-2 py-1 rounded transition-colors",
            onClick: () => setIsEditingTitle(true),
            title: "Click to edit workflow title",
            children: workflowTitle
          }
        ),
        /* @__PURE__ */ jsx7("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx7(
          "button",
          {
            onClick: () => setShowSidebar(!showSidebar),
            className: "p-2 hover:bg-gray-100 rounded-md transition-colors",
            children: /* @__PURE__ */ jsx7(Settings, { className: "w-4 h-4" })
          }
        ) })
      ] }),
      /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
        /* @__PURE__ */ jsxs3(Button, { variant: "outline", size: "sm", children: [
          /* @__PURE__ */ jsx7(Upload, { className: "w-4 h-4 mr-2" }),
          "Import"
        ] }),
        /* @__PURE__ */ jsxs3(Button, { variant: "outline", size: "sm", children: [
          /* @__PURE__ */ jsx7(Download, { className: "w-4 h-4 mr-2" }),
          "Export"
        ] }),
        /* @__PURE__ */ jsxs3(Button, { variant: "default", size: "sm", children: [
          /* @__PURE__ */ jsx7(Play, { className: "w-4 h-4 mr-2" }),
          "Test"
        ] }),
        /* @__PURE__ */ jsxs3(
          Button,
          {
            onClick: saveWorkflow,
            variant: "default",
            size: "sm",
            className: "bg-green-600 hover:bg-green-700",
            children: [
              /* @__PURE__ */ jsx7(Save, { className: "w-4 h-4 mr-2" }),
              "Save"
            ]
          }
        )
      ] })
    ] }),
    /* @__PURE__ */ jsxs3("div", { className: "flex h-[calc(100%-3.5rem)] flex-1", children: [
      showSidebar && /* @__PURE__ */ jsxs3("div", { className: "w-80 bg-white border-r border-gray-200 flex flex-col h-full", children: [
        /* @__PURE__ */ jsxs3("div", { className: "flex border-b border-gray-200", children: [
          /* @__PURE__ */ jsx7(
            "button",
            {
              onClick: () => setSidebarTab("nodes"),
              className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${sidebarTab === "nodes" ? "text-blue-600 border-b-2 border-blue-600 bg-blue-50" : "text-gray-600 hover:text-gray-900"}`,
              children: "Nodes"
            }
          ),
          /* @__PURE__ */ jsx7(
            "button",
            {
              onClick: () => setSidebarTab("properties"),
              className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${sidebarTab === "properties" ? "text-blue-600 border-b-2 border-blue-600 bg-blue-50" : "text-gray-600 hover:text-gray-900"}`,
              children: "Properties"
            }
          )
        ] }),
        /* @__PURE__ */ jsx7("div", { className: "flex-1 overflow-y-auto", children: sidebarTab === "nodes" ? /* @__PURE__ */ jsx7("div", { className: "p-4", children: nodes.length === 0 ? (
          // Show only triggers when canvas is empty
          /* @__PURE__ */ jsxs3("div", { className: "mb-6", children: [
            /* @__PURE__ */ jsx7("h3", { className: "text-sm font-semibold text-gray-900 mb-3 uppercase tracking-wide", children: "Triggers" }),
            /* @__PURE__ */ jsx7("div", { className: "space-y-2", children: nodeGroups["Triggers"].map((node) => /* @__PURE__ */ jsxs3(
              "div",
              {
                draggable: true,
                onDragStart: (event) => onDragStart(event, node.type),
                onClick: () => addNode(node.type),
                className: "w-full flex items-center gap-3 p-3 text-left hover:bg-gray-50 rounded-lg border border-gray-200 transition-colors group cursor-grab active:cursor-grabbing",
                children: [
                  /* @__PURE__ */ jsx7("span", { className: "text-2xl", children: node.icon }),
                  /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
                    /* @__PURE__ */ jsx7("div", { className: "text-sm font-medium text-gray-900 group-hover:text-blue-600", children: node.label }),
                    /* @__PURE__ */ jsx7("div", { className: "text-xs text-gray-500 mt-0.5", children: node.description })
                  ] })
                ]
              },
              node.type
            )) })
          ] })
        ) : (
          // Show action nodes when canvas has nodes (hide triggers)
          Object.entries(nodeGroups).filter(([groupName]) => groupName !== "Triggers").map(([groupName, groupNodes]) => /* @__PURE__ */ jsxs3("div", { className: "mb-6", children: [
            /* @__PURE__ */ jsx7("h3", { className: "text-sm font-semibold text-gray-900 mb-3 uppercase tracking-wide", children: groupName }),
            /* @__PURE__ */ jsx7("div", { className: "space-y-2", children: groupNodes.map((node) => /* @__PURE__ */ jsxs3(
              "div",
              {
                draggable: true,
                onDragStart: (event) => onDragStart(event, node.type),
                onClick: () => addNode(node.type),
                className: "w-full flex items-center gap-3 p-3 text-left hover:bg-gray-50 rounded-lg border border-gray-200 transition-colors group cursor-grab active:cursor-grabbing",
                children: [
                  /* @__PURE__ */ jsx7("span", { className: "text-2xl", children: node.icon }),
                  /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
                    /* @__PURE__ */ jsx7("div", { className: "text-sm font-medium text-gray-900 group-hover:text-blue-600", children: node.label }),
                    /* @__PURE__ */ jsx7("div", { className: "text-xs text-gray-500 mt-0.5", children: node.description })
                  ] })
                ]
              },
              node.type
            )) })
          ] }, groupName))
        ) }) : /* @__PURE__ */ jsx7("div", { className: "p-4", children: selectedNode ? /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
          /* @__PURE__ */ jsxs3("div", { children: [
            /* @__PURE__ */ jsx7("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Node Type" }),
            /* @__PURE__ */ jsx7("div", { className: "text-sm text-gray-900 bg-gray-50 px-3 py-2 rounded-md", children: selectedNode.type })
          ] }),
          /* @__PURE__ */ jsxs3("div", { children: [
            /* @__PURE__ */ jsx7("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Label" }),
            /* @__PURE__ */ jsx7(
              Input,
              {
                type: "text",
                value: selectedNode.data.label,
                onChange: (e) => {
                  setNodes((nds) => nds.map(
                    (n) => n.id === selectedNode.id ? { ...n, data: { ...n.data, label: e.target.value } } : n
                  ));
                  setSelectedNode((prev) => prev ? { ...prev, data: { ...prev.data, label: e.target.value } } : null);
                  forceRerender();
                }
              }
            )
          ] }),
          selectedNode.data.type !== "trigger" && selectedNode.data.content !== void 0 && /* @__PURE__ */ jsxs3("div", { children: [
            /* @__PURE__ */ jsx7("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Content" }),
            /* @__PURE__ */ jsx7(
              Textarea,
              {
                value: selectedNode.data.content || "",
                onChange: (e) => {
                  setNodes((nds) => nds.map(
                    (n) => n.id === selectedNode.id ? { ...n, data: { ...n.data, content: e.target.value } } : n
                  ));
                  setSelectedNode((prev) => prev ? { ...prev, data: { ...prev.data, content: e.target.value } } : null);
                  forceRerender();
                },
                rows: 3
              }
            )
          ] }),
          selectedNode.data.type === "trigger" && /* @__PURE__ */ jsxs3(Fragment, { children: [
            /* @__PURE__ */ jsxs3("div", { children: [
              /* @__PURE__ */ jsx7("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Keywords" }),
              /* @__PURE__ */ jsx7(
                Textarea,
                {
                  placeholder: "hello, help, {{ body }}",
                  value: selectedNode.data.metadata?.keywords || "",
                  onChange: (e) => {
                    setNodes((nds) => nds.map(
                      (n) => n.id === selectedNode.id ? {
                        ...n,
                        data: {
                          ...n.data,
                          metadata: {
                            ...n.data.metadata,
                            keywords: e.target.value
                          }
                        }
                      } : n
                    ));
                    setSelectedNode((prev) => prev ? {
                      ...prev,
                      data: {
                        ...prev.data,
                        metadata: {
                          ...prev.data.metadata,
                          keywords: e.target.value
                        }
                      }
                    } : null);
                    forceRerender();
                  },
                  rows: 3
                }
              ),
              /* @__PURE__ */ jsxs3("p", { className: "text-xs text-gray-500 mt-1", children: [
                "Comma separated keywords or ",
                `{{ body }}`,
                " for full content"
              ] })
            ] }),
            /* @__PURE__ */ jsxs3("div", { children: [
              /* @__PURE__ */ jsx7("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Match Type" }),
              /* @__PURE__ */ jsxs3(
                Select,
                {
                  value: selectedNode.data.metadata?.matchType || "contains",
                  onValueChange: (value) => {
                    setNodes((nds) => nds.map(
                      (n) => n.id === selectedNode.id ? {
                        ...n,
                        data: {
                          ...n.data,
                          metadata: {
                            ...n.data.metadata,
                            matchType: value
                          }
                        }
                      } : n
                    ));
                    setSelectedNode((prev) => prev ? {
                      ...prev,
                      data: {
                        ...prev.data,
                        metadata: {
                          ...prev.data.metadata,
                          matchType: value
                        }
                      }
                    } : null);
                    forceRerender();
                  },
                  children: [
                    /* @__PURE__ */ jsx7(SelectTrigger, { children: /* @__PURE__ */ jsx7(SelectValue, { placeholder: "Select match type" }) }),
                    /* @__PURE__ */ jsxs3(SelectContent, { children: [
                      /* @__PURE__ */ jsx7(SelectItem, { value: "contains", children: "Contains" }),
                      /* @__PURE__ */ jsx7(SelectItem, { value: "exact", children: "Exact Match" }),
                      /* @__PURE__ */ jsx7(SelectItem, { value: "starts_with", children: "Starts With" }),
                      /* @__PURE__ */ jsx7(SelectItem, { value: "ends_with", children: "Ends With" })
                    ] })
                  ]
                }
              )
            ] }),
            /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
              /* @__PURE__ */ jsxs3("div", { children: [
                /* @__PURE__ */ jsx7("label", { htmlFor: "exactMatch", className: "text-sm font-medium text-gray-700", children: "Exact Match (case sensitive)" }),
                /* @__PURE__ */ jsx7("p", { className: "text-xs text-gray-500 mt-1", children: "Enable case-sensitive matching" })
              ] }),
              /* @__PURE__ */ jsx7("div", { className: "flex items-center", children: /* @__PURE__ */ jsx7(
                Switch,
                {
                  checked: selectedNode.data.metadata?.exactMatch || false,
                  onCheckedChange: (checked) => {
                    console.log("Switch toggled:", { checked, nodeId: selectedNode.id });
                    setNodes((nds) => nds.map(
                      (n) => n.id === selectedNode.id ? {
                        ...n,
                        data: {
                          ...n.data,
                          metadata: {
                            ...n.data.metadata,
                            exactMatch: checked
                          }
                        }
                      } : n
                    ));
                    setSelectedNode((prev) => prev ? {
                      ...prev,
                      data: {
                        ...prev.data,
                        metadata: {
                          ...prev.data.metadata,
                          exactMatch: checked
                        }
                      }
                    } : null);
                  }
                }
              ) })
            ] })
          ] }),
          selectedNode.data.type === "delay" && /* @__PURE__ */ jsxs3("div", { children: [
            /* @__PURE__ */ jsx7("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Delay Duration (milliseconds)" }),
            /* @__PURE__ */ jsx7(
              Input,
              {
                type: "number",
                min: "0",
                step: "100",
                value: selectedNode.data.metadata?.delay || 300,
                onChange: (e) => {
                  const delayValue = parseInt(e.target.value) || 300;
                  setNodes((nds) => nds.map(
                    (n) => n.id === selectedNode.id ? {
                      ...n,
                      data: {
                        ...n.data,
                        metadata: {
                          ...n.data.metadata,
                          delay: delayValue
                        }
                      }
                    } : n
                  ));
                  setSelectedNode((prev) => prev ? {
                    ...prev,
                    data: {
                      ...prev.data,
                      metadata: {
                        ...prev.data.metadata,
                        delay: delayValue
                      }
                    }
                  } : null);
                  forceRerender();
                },
                placeholder: "300"
              }
            ),
            /* @__PURE__ */ jsx7("p", { className: "text-xs text-gray-500 mt-1", children: "Delay in milliseconds (default: 300ms)" })
          ] }),
          /* @__PURE__ */ jsxs3(
            Button,
            {
              onClick: () => deleteNode(selectedNode.id),
              variant: "destructive",
              className: "w-full",
              children: [
                /* @__PURE__ */ jsx7(Trash2, { className: "w-4 h-4 mr-2" }),
                "Delete Node"
              ]
            }
          )
        ] }) : /* @__PURE__ */ jsxs3("div", { className: "text-center py-8", children: [
          /* @__PURE__ */ jsx7("div", { className: "text-gray-400 mb-2", children: /* @__PURE__ */ jsx7(Settings, { className: "w-8 h-8 mx-auto" }) }),
          /* @__PURE__ */ jsx7("p", { className: "text-sm text-gray-500", children: "Select a node to edit its properties" })
        ] }) }) })
      ] }),
      /* @__PURE__ */ jsxs3("div", { className: `flex-1 relative ${isDragOver ? "bg-blue-50 border-2 border-dashed border-blue-300" : ""}`, children: [
        /* @__PURE__ */ jsxs3(
          ReactFlow,
          {
            nodes,
            edges,
            onNodesChange,
            onEdgesChange,
            onConnect,
            onNodeClick: handleNodeClick,
            onEdgeClick: handleEdgeClick,
            onInit,
            onDrop,
            onDragOver,
            onDragLeave,
            nodeTypes: memoizedNodeTypes,
            fitView: true,
            attributionPosition: "bottom-left",
            className: "bg-gray-50",
            children: [
              /* @__PURE__ */ jsx7(Background, { color: "#e5e7eb", gap: 20 }),
              /* @__PURE__ */ jsx7(Controls, { className: "bg-white border border-gray-200 rounded-lg shadow-sm" }),
              /* @__PURE__ */ jsx7(
                MiniMap,
                {
                  className: "bg-white border border-gray-200 rounded-lg shadow-sm",
                  nodeColor: "#3b82f6",
                  maskColor: "rgba(0, 0, 0, 0.1)"
                }
              )
            ]
          }
        ),
        nodes.length === 0 && !isDragOver && /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
          /* @__PURE__ */ jsx7(
            "button",
            {
              onClick: () => setShowTriggerPopup(true),
              className: "mx-auto w-16 h-16 bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg hover:shadow-xl transition-all duration-200 flex items-center justify-center pointer-events-auto group",
              children: /* @__PURE__ */ jsx7(Plus, { className: "w-8 h-8 group-hover:scale-110 transition-transform" })
            }
          ),
          /* @__PURE__ */ jsx7("p", { className: "mt-4 text-sm text-gray-500 font-medium", children: "Click to add your first node" })
        ] }) }),
        isDragOver && /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
          /* @__PURE__ */ jsx7("div", { className: "w-20 h-20 bg-blue-100 border-4 border-dashed border-blue-400 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx7(Plus, { className: "w-10 h-10 text-blue-600" }) }),
          /* @__PURE__ */ jsx7("p", { className: "mt-4 text-lg text-blue-600 font-semibold", children: "Drop node here" })
        ] }) })
      ] })
    ] }),
    showTriggerPopup && /* @__PURE__ */ jsx7("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ jsxs3("div", { className: "bg-white rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] overflow-hidden", children: [
      /* @__PURE__ */ jsx7("div", { className: "p-6 border-b border-gray-200", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
        /* @__PURE__ */ jsx7("h2", { className: "text-lg font-semibold text-gray-900", children: "Choose a Trigger" }),
        /* @__PURE__ */ jsx7(
          "button",
          {
            onClick: () => setShowTriggerPopup(false),
            className: "text-gray-400 hover:text-gray-600",
            children: /* @__PURE__ */ jsx7(Plus, { className: "w-6 h-6 rotate-45" })
          }
        )
      ] }) }),
      /* @__PURE__ */ jsx7("div", { className: "p-6 overflow-y-auto max-h-[60vh]", children: /* @__PURE__ */ jsxs3("div", { className: "mb-6", children: [
        /* @__PURE__ */ jsx7("h3", { className: "text-sm font-semibold text-gray-900 mb-3 uppercase tracking-wide", children: "Triggers" }),
        /* @__PURE__ */ jsx7("div", { className: "grid grid-cols-2 gap-3", children: nodeGroups["Triggers"].map((node) => /* @__PURE__ */ jsxs3(
          "div",
          {
            draggable: true,
            onDragStart: (event) => onDragStart(event, node.type),
            onClick: () => addNode(node.type),
            className: "flex items-center gap-3 p-4 text-left hover:bg-gray-50 rounded-lg border border-gray-200 transition-colors group cursor-grab active:cursor-grabbing",
            children: [
              /* @__PURE__ */ jsx7("span", { className: "text-2xl", children: node.icon }),
              /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
                /* @__PURE__ */ jsx7("div", { className: "text-sm font-medium text-gray-900 group-hover:text-blue-600", children: node.label }),
                /* @__PURE__ */ jsx7("div", { className: "text-xs text-gray-500 mt-0.5", children: node.description })
              ] })
            ]
          },
          node.type
        )) })
      ] }) })
    ] }) })
  ] });
};
var FacebookWorkflowWithProvider = (props) => /* @__PURE__