diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index e1bd47e..35b2ab4 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,16 +1,16 @@ import { useState } from "react"; -import { MessageSquare, Image, Mic, ArrowLeft, Plus, ChevronLeft, ChevronRight, Bot } from "lucide-react"; +import { MessageSquare, Image, Mic, ArrowLeft, Plus, ChevronLeft, ChevronRight, Bot, FileText } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; import { ThemeToggle } from "@/components/ThemeToggle"; interface LayoutProps { children: React.ReactNode; - activeTab: "chat" | "images" | "audio" | "bots"; - onTabChange: (tab: "chat" | "images" | "audio" | "bots") => void; + activeTab: "chat" | "images" | "audio" | "bots" | "agent"; + onTabChange: (tab: "chat" | "images" | "audio" | "bots" | "agent") => void; } -type TabType = "chat" | "images" | "audio" | "bots"; +type TabType = "chat" | "images" | "audio" | "bots" | "agent"; export const Layout = ({ children, activeTab, onTabChange }: LayoutProps) => { const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false); @@ -20,6 +20,7 @@ export const Layout = ({ children, activeTab, onTabChange }: LayoutProps) => { { id: "images" as TabType, label: "Imagens", icon: Image }, { id: "audio" as TabType, label: "Áudio", icon: Mic }, { id: "bots" as TabType, label: "Bots", icon: Bot }, + { id: "agent" as TabType, label: "Agente de Parecer", icon: FileText }, ]; return ( diff --git a/src/components/agent/AgentChat.tsx b/src/components/agent/AgentChat.tsx new file mode 100644 index 0000000..1b92085 --- /dev/null +++ b/src/components/agent/AgentChat.tsx @@ -0,0 +1,195 @@ +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Textarea } from "@/components/ui/textarea"; +import { Input } from "@/components/ui/input"; +import { Download, Send, Sparkles } from "lucide-react"; +import { LegalOpinion } from "./AgentView"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { useToast } from "@/hooks/use-toast"; + +interface AgentChatProps { + selectedOpinion: LegalOpinion | null; + isCreatingNew: boolean; + onOpinionCreated: (opinion: LegalOpinion) => void; +} + +export const AgentChat = ({ + selectedOpinion, + isCreatingNew, + onOpinionCreated, +}: AgentChatProps) => { + const [title, setTitle] = useState(""); + const [instructions, setInstructions] = useState(""); + const [category, setCategory] = useState(""); + const [generatedContent, setGeneratedContent] = useState(""); + const [isGenerating, setIsGenerating] = useState(false); + const { toast } = useToast(); + + const handleGenerate = async () => { + if (!instructions.trim()) { + toast({ + title: "Instruções necessárias", + description: "Por favor, forneça instruções para gerar o parecer.", + variant: "destructive", + }); + return; + } + + setIsGenerating(true); + + // Simulação de chamada à IA - aqui você integraria com a API real + setTimeout(() => { + const mockContent = `PARECER JURÍDICO + +TÍTULO: ${title || "Parecer Jurídico"} + +${instructions} + +ANÁLISE: + +Este parecer foi gerado com base nas instruções fornecidas. A análise considera os seguintes aspectos legais: + +1. Fundamentação Legal +2. Precedentes Judiciais +3. Doutrina Aplicável +4. Conclusão e Recomendações + +CONCLUSÃO: + +Com base na análise realizada, conclui-se que... + +___________________________ +Parecer gerado em ${new Date().toLocaleDateString('pt-BR')}`; + + setGeneratedContent(mockContent); + setIsGenerating(false); + + if (isCreatingNew) { + const newOpinion: LegalOpinion = { + id: Date.now().toString(), + title: title || "Novo Parecer", + content: mockContent, + createdAt: new Date(), + category: category || undefined, + }; + onOpinionCreated(newOpinion); + } + + toast({ + title: "Parecer gerado com sucesso!", + description: "O parecer está pronto para download.", + }); + }, 2000); + }; + + const handleDownloadDocx = () => { + // Aqui você implementaria a geração real do DOCX + // Por enquanto, vamos criar um arquivo de texto + const content = generatedContent || selectedOpinion?.content || ""; + const blob = new Blob([content], { type: 'text/plain' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `${title || selectedOpinion?.title || 'parecer'}.txt`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + + toast({ + title: "Download iniciado", + description: "O parecer está sendo baixado.", + }); + }; + + const displayContent = generatedContent || selectedOpinion?.content; + + return ( +
+
+

+ {selectedOpinion ? selectedOpinion.title : "Novo Parecer Jurídico"} +

+ {selectedOpinion && ( +

+ Criado em {new Date(selectedOpinion.createdAt).toLocaleDateString('pt-BR')} +

+ )} +
+ +
+
+ {(isCreatingNew || !selectedOpinion) && ( + <> +
+ + setTitle(e.target.value)} + placeholder="Ex: Análise sobre Contrato de Prestação de Serviços" + /> +
+
+ + setCategory(e.target.value)} + placeholder="Ex: Direito Civil, Trabalhista, etc." + /> +
+ + )} + +
+ +