import { BrowserFrame } from "@/components/Browser/BrowserFrame"; import { useState, useEffect, type ElementType } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Database, Plus, Trash2, Play, Settings, BookOpen, Link, CheckCircle, XCircle, Loader2, Clock, Zap, Package, ExternalLink, Search, Brain, Code, Network, Boxes, ArrowRight, MessageCircle, BarChart3, Compass, Handshake, Factory, Headphones, Calculator, Layers, Home, Bot, Globe, Workflow, Palette, Building2, Users, Crown, UserCog, DollarSign, Edit, ChevronDown, ChevronRight, Receipt, Wallet, Hash, Plug, Share2, ShoppingCart, FileText, Store, GraduationCap, Server, Terminal, Layout, Blocks, ThumbsUp, Shield, HardDrive, Wrench, ClipboardCheck, PenTool, MapPin, Github, Activity, Gauge, Signal, Square, AlertCircle, RefreshCw, Cpu, Sparkles, ArrowDown, } from "lucide-react"; import { useLocation } from "wouter"; import { Badge } from "@/components/ui/badge"; import { Switch } from "@/components/ui/switch"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "@/components/ui/dialog"; interface ErpConnection { id: number; name: string; type: string; baseUrl: string; isActive: string; createdAt: string; } interface AgentTask { id: number; name: string; type: string; schedule: string | null; erpConnectionId: number | null; config: string | null; status: string | null; lastRun: string | null; nextRun: string | null; createdAt: string; } interface KnowledgeBaseEntry { id: number; title: string; content: string; author: string; category: string; source: string | null; createdAt: string; } interface LibraryPackage { name: string; version: string; type: string; category: string; } interface LibrariesData { nodejs: { dependencies: LibraryPackage[]; devDependencies: LibraryPackage[]; total: number; }; python: { dependencies: LibraryPackage[]; total: number; note?: string; }; } async function fetchConnections(): Promise { const response = await fetch("/api/soe/connections", { credentials: "include" }); if (!response.ok) throw new Error("Failed to fetch connections"); return response.json(); } async function fetchTasks(): Promise { const response = await fetch("/api/soe/tasks", { credentials: "include" }); if (!response.ok) throw new Error("Failed to fetch tasks"); return response.json(); } async function fetchKnowledgeBase(): Promise { const response = await fetch("/api/knowledge-base", { credentials: "include" }); if (!response.ok) throw new Error("Failed to fetch knowledge base"); return response.json(); } async function fetchLibraries(): Promise { const response = await fetch("/api/admin/libraries", { credentials: "include" }); if (!response.ok) throw new Error("Failed to fetch libraries"); return response.json(); } export default function Admin() { const queryClient = useQueryClient(); const [activeTab, setActiveTab] = useState("connections"); const [newConnection, setNewConnection] = useState({ name: "", type: "arcadia_plus", baseUrl: "", apiKey: "", apiSecret: "", }); const [newTask, setNewTask] = useState({ name: "", type: "financial_analysis", schedule: "", erpConnectionId: "", }); const [newKbEntry, setNewKbEntry] = useState({ title: "", content: "", author: "", category: "tributacao", source: "", }); const { data: connections = [], isLoading: loadingConnections } = useQuery({ queryKey: ["erp-connections"], queryFn: fetchConnections, }); const { data: tasks = [], isLoading: loadingTasks } = useQuery({ queryKey: ["erp-tasks"], queryFn: fetchTasks, }); const { data: knowledgeBase = [], isLoading: loadingKb } = useQuery({ queryKey: ["knowledge-base"], queryFn: fetchKnowledgeBase, }); const { data: libraries, isLoading: loadingLibraries } = useQuery({ queryKey: ["admin-libraries"], queryFn: fetchLibraries, }); const [librarySearch, setLibrarySearch] = useState(""); const [libraryFilter, setLibraryFilter] = useState("all"); const createConnectionMutation = useMutation({ mutationFn: async (data: typeof newConnection) => { const response = await fetch("/api/soe/connections", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), credentials: "include", }); if (!response.ok) throw new Error("Failed to create connection"); return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["erp-connections"] }); setNewConnection({ name: "", type: "arcadia_plus", baseUrl: "", apiKey: "", apiSecret: "" }); }, }); const testConnectionMutation = useMutation({ mutationFn: async (id: number) => { const response = await fetch(`/api/soe/connections/${id}/test`, { method: "POST", credentials: "include", }); return response.json(); }, }); const deleteConnectionMutation = useMutation({ mutationFn: async (id: number) => { await fetch(`/api/soe/connections/${id}`, { method: "DELETE", credentials: "include", }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["erp-connections"] }); }, }); const createTaskMutation = useMutation({ mutationFn: async (data: typeof newTask) => { const response = await fetch("/api/soe/tasks", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ...data, erpConnectionId: data.erpConnectionId ? parseInt(data.erpConnectionId) : null, }), credentials: "include", }); if (!response.ok) throw new Error("Failed to create task"); return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["erp-tasks"] }); setNewTask({ name: "", type: "financial_analysis", schedule: "", erpConnectionId: "" }); }, }); const executeTaskMutation = useMutation({ mutationFn: async (id: number) => { const response = await fetch(`/api/soe/tasks/${id}/execute`, { method: "POST", credentials: "include", }); return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["erp-tasks"] }); }, }); const deleteTaskMutation = useMutation({ mutationFn: async (id: number) => { await fetch(`/api/soe/tasks/${id}`, { method: "DELETE", credentials: "include", }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["erp-tasks"] }); }, }); const createKbMutation = useMutation({ mutationFn: async (data: typeof newKbEntry) => { const response = await fetch("/api/knowledge-base", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), credentials: "include", }); if (!response.ok) throw new Error("Failed to create knowledge base entry"); return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["knowledge-base"] }); setNewKbEntry({ title: "", content: "", author: "", category: "tributacao", source: "" }); }, }); const deleteKbMutation = useMutation({ mutationFn: async (id: number) => { await fetch(`/api/knowledge-base/${id}`, { method: "DELETE", credentials: "include", }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["knowledge-base"] }); }, }); const taskTypes = [ { value: "financial_analysis", label: "Análise Financeira" }, { value: "inventory_monitoring", label: "Monitoramento de Estoque" }, { value: "sales_report", label: "Relatório de Vendas" }, { value: "payables_alert", label: "Alertas de Contas a Pagar" }, { value: "receivables_alert", label: "Alertas de Contas a Receber" }, ]; const kbCategories = [ { value: "tributacao", label: "Tributação" }, { value: "juridico", label: "Jurídico" }, { value: "contabil", label: "Contábil" }, { value: "financeiro", label: "Financeiro" }, { value: "processos", label: "Processos" }, { value: "politicas", label: "Políticas" }, ]; return (

Administração

Gerencie conexões SOE, tarefas e base de conhecimento

Conexões SOE Tarefas Autônomas Base de Conhecimento Bibliotecas Módulos Casa de Máquinas
Nova Conexão Motor Conecte ao Arcádia Plus ou ERPNext
setNewConnection({ ...newConnection, name: e.target.value })} placeholder="Ex: Produção Arcadia Plus" data-testid="input-connection-name" />
setNewConnection({ ...newConnection, baseUrl: e.target.value })} placeholder="https://api.arcadiaplus.com.br" data-testid="input-base-url" />
setNewConnection({ ...newConnection, apiKey: e.target.value })} placeholder="Sua chave de API" data-testid="input-api-key" />
setNewConnection({ ...newConnection, apiSecret: e.target.value })} placeholder="Seu secret" data-testid="input-api-secret" />
Conexões Ativas {connections.length} conexões configuradas {loadingConnections ? (
) : connections.length === 0 ? (
Nenhuma conexão configurada
) : (
{connections.map((conn) => (
{conn.name}
Tipo: {conn.type === "arcadia_plus" ? "Arcádia Plus" : "ERPNext"}
URL: {conn.baseUrl}
))}
)}
Nova Tarefa Autônoma Configure tarefas que o agente executará automaticamente
setNewTask({ ...newTask, name: e.target.value })} placeholder="Ex: Análise Diária de Balanço" data-testid="input-task-name" />
setNewTask({ ...newTask, schedule: e.target.value })} placeholder="Ex: 0 8 * * * (diário às 8h)" data-testid="input-task-schedule" />
Tarefas Configuradas {tasks.length} tarefas ativas {loadingTasks ? (
) : tasks.length === 0 ? (
Nenhuma tarefa configurada
) : (
{tasks.map((task) => (
{task.name}
Tipo: {taskTypes.find(t => t.value === task.type)?.label || task.type}
{task.lastRun && (
Última execução: {new Date(task.lastRun).toLocaleString("pt-BR")}
)}
))}
)}
Novo Documento Adicione conhecimento à Inteligência Arcádia Business
setNewKbEntry({ ...newKbEntry, title: e.target.value })} placeholder="Ex: Guia de ICMS para Comércio Eletrônico" data-testid="input-kb-title" />
setNewKbEntry({ ...newKbEntry, author: e.target.value })} placeholder="Ex: Dr. João Silva" data-testid="input-kb-author" />
setNewKbEntry({ ...newKbEntry, source: e.target.value })} placeholder="Ex: Decreto 1234/2024" data-testid="input-kb-source" />