File size: 4,843 Bytes
c675f75 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
import Editor from "@monaco-editor/react";
import { ChevronUp, ChevronDown, Trash2, Power } from "lucide-react";
import { useMemo } from "react";
import { extractFunctionAndRenderer, generateSchemaFromCode } from "../utils";
export interface Tool {
id: number;
name: string;
code: string;
enabled: boolean;
isCollapsed?: boolean;
renderer?: string;
}
interface ToolItemProps {
tool: Tool;
onToggleEnabled: () => void;
onToggleCollapsed: () => void;
onExpand: () => void;
onDelete: () => void;
onCodeChange: (newCode: string) => void;
}
const ToolItem: React.FC<ToolItemProps> = ({
tool,
onToggleEnabled,
onToggleCollapsed,
onDelete,
onCodeChange,
}) => {
const { functionCode } = extractFunctionAndRenderer(tool.code);
const schema = useMemo(
() => generateSchemaFromCode(functionCode),
[functionCode],
);
return (
<div
className={`rounded-2xl p-5 border border-white/10 bg-white/5 backdrop-blur-sm transition-all shadow-[0_18px_55px_rgba(3,27,78,0.45)] ${!tool.enabled ? "opacity-40" : ""}`}
>
<div
className="flex justify-between items-center cursor-pointer"
onClick={onToggleCollapsed}
>
<div>
<h3 className="text-lg font-semibold text-[#78a9ff] font-mono">
{schema.name}
</h3>
<div className="text-xs text-[#a6c8ff]/80 mt-1">
{schema.description}
</div>
</div>
<div className="flex items-center space-x-3">
<button
onClick={(e) => {
e.stopPropagation();
onToggleEnabled();
}}
className={`p-1.5 rounded-full border transition-all ${tool.enabled ? "border-[#0f62fe]/50 bg-[#0f62fe]/20 text-[#78a9ff]" : "border-white/15 bg-white/5 text-white/60"}`}
>
<Power size={18} />
</button>
<button
onClick={(e) => {
e.stopPropagation();
onDelete();
}}
className="p-2 text-[#ff8389] hover:text-white border border-transparent hover:border-[#ff8389]/40 hover:bg-[#ff8389]/10 rounded-full transition-all"
>
<Trash2 size={18} />
</button>
<button
onClick={(e) => {
e.stopPropagation();
onToggleCollapsed();
}}
className="p-2 text-white/70 hover:text-white border border-white/10 hover:border-white/30 hover:bg-white/10 rounded-full transition-all"
>
{tool.isCollapsed ? (
<ChevronDown size={20} />
) : (
<ChevronUp size={20} />
)}
</button>
</div>
</div>
{!tool.isCollapsed && (
<div className="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="md:col-span-2">
<label className="text-xs font-semibold uppercase tracking-[0.2em] text-[#a6c8ff]/80">
Implementation & Renderer
</label>
<div
className="mt-1 rounded-2xl overflow-visible border border-white/12 bg-[#031b4e]/60"
style={{ overflow: "visible" }}
>
<Editor
height="300px"
language="javascript"
theme="vs-dark"
value={tool.code}
onChange={(value) => onCodeChange(value || "")}
options={{
minimap: { enabled: false },
scrollbar: { verticalScrollbarSize: 10 },
fontSize: 14,
lineDecorationsWidth: 0,
lineNumbersMinChars: 3,
scrollBeyondLastLine: false,
}}
/>
</div>
</div>
<div className="flex flex-col">
<label className="text-xs font-semibold uppercase tracking-[0.2em] text-[#a6c8ff]/80">
Generated Schema
</label>
<div className="mt-1 rounded-2xl flex-grow overflow-visible border border-white/12 bg-[#031b4e]/60">
<Editor
height="300px"
language="json"
theme="vs-dark"
value={JSON.stringify(schema, null, 2)}
options={{
readOnly: true,
minimap: { enabled: false },
scrollbar: { verticalScrollbarSize: 10 },
lineNumbers: "off",
glyphMargin: false,
folding: false,
lineDecorationsWidth: 0,
lineNumbersMinChars: 0,
scrollBeyondLastLine: false,
fontSize: 12,
}}
/>
</div>
</div>
</div>
)}
</div>
);
};
export default ToolItem;
|