PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.8.1
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.8.1
8.8.1 8.8.0 8.7.9 8.7.8 8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 All 537 releases
chatbot / addons / automator / src / components / Sidebar.jsx

Sidebar.jsx in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.8.1, at addons/automator/src/components/Sidebar.jsx

137 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use client";
2
3 import React, { useState } from "react";
4 import { Search, Plus, Minus, GitBranch } from "lucide-react";
5 import { Input } from "./ui/Input";
6 import { appsMetadata as apps } from "../constants/appsMetadata";
7
8 const tools = [
9 // { id: "t1", name: "HTTP Request", icon: "H", iconBg: "bg-slate-700" },
10 // { id: "t2", name: "Code", icon: "<>", iconBg: "bg-emerald-600" },
11 { id: "t3", name: "Webhook", icon: "W", iconBg: "bg-violet-600" },
12 // { id: "t4", name: "Schedule", icon: "S", iconBg: "bg-amber-500" },
13 // { id: "t5", name: "Filter", icon: "F", iconBg: "bg-cyan-600" },
14 // { id: "t6", name: "Merge", icon: "M", iconBg: "bg-pink-500" },
15 // { id: "t7", name: "Split", icon: "Sp", iconBg: "bg-teal-500" },
16 // { id: "t8", name: "Wait", icon: "W", iconBg: "bg-gray-500" },
17 ];
18
19 export function Sidebar({ onZoomIn, onZoomOut, onAddRouter, onAddNode }) {
20 const [search, setSearch] = useState("");
21 const [activeTab, setActiveTab] = useState("apps");
22 const [draggedItem, setDraggedItem] = useState(null);
23
24 const items = activeTab === "apps" ? apps : tools;
25 const filteredItems = items.filter((item) =>
26 item.name.toLowerCase().includes(search.toLowerCase())
27 );
28
29 const handleDragStart = (e, app) => {
30 setDraggedItem(app.id);
31 e.dataTransfer.setData("application/json", JSON.stringify(app));
32 e.dataTransfer.effectAllowed = "copy";
33 };
34
35 const handleDragEnd = () => {
36 setDraggedItem(null);
37 };
38
39 return (
40 <div className="w-64 bg-sidebar border-r border-sidebar-border flex flex-col h-full">
41 <div className="p-3">
42 <div className="relative">
43 <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
44 <Input
45 placeholder="Search"
46 value={search}
47 onChange={(e) => setSearch(e.target.value)}
48 className="pl-9 bg-input border-border"
49 />
50 </div>
51 </div>
52
53 <div className="flex border-b border-sidebar-border">
54 <button
55 onClick={() => setActiveTab("apps")}
56 className={`flex-1 py-2 text-sm font-medium transition-colors ${
57 activeTab === "apps"
58 ? "text-sidebar-foreground border-b-2 border-sidebar-primary"
59 : "text-muted-foreground hover:text-sidebar-foreground"
60 }`}
61 >
62 Apps
63 </button>
64 <button
65 onClick={() => setActiveTab("tools")}
66 className={`flex-1 py-2 text-sm font-medium transition-colors ${
67 activeTab === "tools"
68 ? "text-sidebar-foreground border-b-2 border-sidebar-primary"
69 : "text-muted-foreground hover:text-sidebar-foreground"
70 }`}
71 >
72 Tools
73 </button>
74 </div>
75
76
77 <div className="flex-1 overflow-y-auto">
78 <div
79 onClick={onAddRouter}
80 draggable
81 onDragStart={(e) => handleDragStart(e, { id: "router", name: "Router", type: "router" })}
82 onDragEnd={handleDragEnd}
83 className={`w-full flex items-center gap-3 px-3 py-2.5 hover:bg-sidebar-accent transition-colors text-left border-b border-sidebar-border cursor-grab active:cursor-grabbing ${
84 draggedItem === "router" ? "opacity-50" : ""
85 }`}
86 >
87 <div className="w-8 h-8 rounded-lg bg-slate-500 flex items-center justify-center text-white">
88 <GitBranch className="w-4 h-4" />
89 </div>
90 <span className="text-sm text-sidebar-foreground">Add Router</span>
91 </div>
92
93 {filteredItems.map((item) => (
94 <div
95 key={item.id}
96 onClick={() => onAddNode(item)}
97 draggable
98 onDragStart={(e) => handleDragStart(e, item)}
99 onDragEnd={handleDragEnd}
100 className={`w-full flex items-center gap-3 px-3 py-2.5 hover:bg-sidebar-accent transition-colors text-left cursor-grab active:cursor-grabbing ${
101 draggedItem === item.id ? "opacity-50" : ""
102 }`}
103 >
104 <div
105 className={`w-8 h-8 rounded-lg ${item.iconBg} flex items-center justify-center text-white text-xs font-semibold`}
106 >
107 {item.icon}
108 </div>
109 <span className="text-sm text-sidebar-foreground truncate">
110 {item.name}
111 </span>
112 </div>
113 ))}
114 </div>
115
116 <div className="p-3 border-t border-sidebar-border flex items-center gap-2">
117 <button
118 onClick={onZoomIn}
119 className="p-2 hover:bg-sidebar-accent rounded-md transition-colors"
120 title="Zoom In"
121 >
122 <Plus className="h-4 w-4 text-muted-foreground" />
123 </button>
124 <button
125 onClick={onZoomOut}
126 className="p-2 hover:bg-sidebar-accent rounded-md transition-colors"
127 title="Zoom Out"
128 >
129 <Minus className="h-4 w-4 text-muted-foreground" />
130 </button>
131 </div>
132 </div>
133 );
134 }
135
136 export default Sidebar;
137