From 7a73be703fc4c8ccc1bb818197a68235a8ae6da2 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 14:14:58 +0000 Subject: [PATCH] feat: Implement prompt versioning and editing --- src/components/prompts/EditPromptDialog.tsx | 356 ++++++++++++++++++++ src/pages/Prompts.tsx | 30 +- 2 files changed, 385 insertions(+), 1 deletion(-) create mode 100644 src/components/prompts/EditPromptDialog.tsx diff --git a/src/components/prompts/EditPromptDialog.tsx b/src/components/prompts/EditPromptDialog.tsx new file mode 100644 index 0000000..02d54f1 --- /dev/null +++ b/src/components/prompts/EditPromptDialog.tsx @@ -0,0 +1,356 @@ +import { useState, useEffect } from "react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Wand2, GitBranch } from "lucide-react"; + +interface EditPromptDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; + prompt: { + id: number; + title: string; + systemPrompt?: string; + version?: string; + } | null; +} + +export function EditPromptDialog({ open, onOpenChange, prompt }: EditPromptDialogProps) { + const [title, setTitle] = useState(""); + const [systemPrompt, setSystemPrompt] = useState(""); + const [versionType, setVersionType] = useState<"major" | "minor" | "patch">("minor"); + const [changeDescription, setChangeDescription] = useState(""); + + // Assistente fields + const [agentName, setAgentName] = useState(""); + const [agentRole, setAgentRole] = useState(""); + const [targetAudience, setTargetAudience] = useState(""); + const [mainObjective, setMainObjective] = useState(""); + const [toneOfVoice, setToneOfVoice] = useState(""); + const [forbiddenPatterns, setForbiddenPatterns] = useState(""); + const [refinementInstructions, setRefinementInstructions] = useState(""); + const [isGenerated, setIsGenerated] = useState(false); + + // Carregar dados do prompt quando o dialog abrir + useEffect(() => { + if (prompt && open) { + setTitle(prompt.title); + setSystemPrompt(prompt.systemPrompt || ""); + setChangeDescription(""); + setVersionType("minor"); + } + }, [prompt, open]); + + const handleGeneratePrompt = () => { + let generatedPrompt = `Você é ${agentName}, ${agentRole}. + +Público-alvo: ${targetAudience} + +Objetivo principal: ${mainObjective} + +Tom de voz: ${toneOfVoice} + +${forbiddenPatterns ? `Padrões proibidos:\n${forbiddenPatterns}` : ''} + +Siga estas diretrizes em todas as suas interações.`; + + if (refinementInstructions && isGenerated) { + generatedPrompt += `\n\nInstruções adicionais:\n${refinementInstructions}`; + } + + setSystemPrompt(generatedPrompt); + setIsGenerated(true); + }; + + const handleStartOver = () => { + setAgentName(""); + setAgentRole(""); + setTargetAudience(""); + setMainObjective(""); + setToneOfVoice(""); + setForbiddenPatterns(""); + setRefinementInstructions(""); + setSystemPrompt(""); + setIsGenerated(false); + }; + + const handleSave = () => { + console.log("Salvando nova versão:", { + promptId: prompt?.id, + title, + systemPrompt, + versionType, + changeDescription + }); + // Aqui você implementaria a lógica de salvar nova versão no backend + onOpenChange(false); + }; + + const getVersionDescription = () => { + switch (versionType) { + case "major": + return "Mudanças significativas que alteram a funcionalidade principal"; + case "minor": + return "Novas funcionalidades ou melhorias sem quebrar compatibilidade"; + case "patch": + return "Correções e ajustes menores"; + } + }; + + if (!prompt) return null; + + return ( + + + + Editar Prompt + + Edite o prompt manualmente ou use o assistente. Uma nova versão será criada preservando o histórico. + + + + + + + + Versão atual: {prompt.version || "1.0.0"} + + + + + Título + setTitle(e.target.value)} + /> + + + + + Manual + + + Assistente + + + + + + System Prompt + setSystemPrompt(e.target.value)} + className="min-h-[400px] font-mono text-sm" + /> + + + + + + + Nome do Agente + setAgentName(e.target.value)} + /> + + + + Função / Papel do Agente + setAgentRole(e.target.value)} + /> + + + + + Público-alvo + setTargetAudience(e.target.value)} + /> + + + + Objetivo Principal + setMainObjective(e.target.value)} + className="min-h-[80px]" + /> + + + + Tom de Voz + + + + + + Amigável + Formal + Técnico + Educado + Institucional + Neutro + Engraçado + + + + + + Padrões Proibidos + setForbiddenPatterns(e.target.value)} + className="min-h-[100px]" + /> + + + + + + {isGenerated ? "Regenerar Prompt" : "Gerar System Prompt"} + + {isGenerated && ( + + Começar do Zero + + )} + + + {systemPrompt && ( + + + Prompt Gerado + setSystemPrompt(e.target.value)} + className="min-h-[400px] font-mono text-sm" + /> + + + + + Instruções Adicionais (opcional) + + setRefinementInstructions(e.target.value)} + className="min-h-[100px]" + /> + + + Aplicar Refinamento + + + + )} + + + + + + Tipo de Versão + setVersionType(v as "major" | "minor" | "patch")}> + + + + + + + Major (X.0.0) + Mudanças significativas + + + + + Minor (0.X.0) + Novas funcionalidades + + + + + Patch (0.0.X) + Correções menores + + + + + {getVersionDescription()} + + + + Descrição das Mudanças + setChangeDescription(e.target.value)} + className="min-h-[100px]" + /> + + + + + onOpenChange(false)}> + Cancelar + + + Salvar Nova Versão + + + + + + ); +} diff --git a/src/pages/Prompts.tsx b/src/pages/Prompts.tsx index e614feb..c05717e 100644 --- a/src/pages/Prompts.tsx +++ b/src/pages/Prompts.tsx @@ -1,6 +1,7 @@ import { useState, useMemo } from "react"; import { PromptCard } from "@/components/prompts/PromptCard"; import { CreatePromptDialog } from "@/components/prompts/CreatePromptDialog"; +import { EditPromptDialog } from "@/components/prompts/EditPromptDialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { @@ -18,6 +19,8 @@ const ITEMS_PER_PAGE = 6; export default function Prompts() { const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); + const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); + const [selectedPrompt, setSelectedPrompt] = useState(null); const [searchQuery, setSearchQuery] = useState(""); const [currentPage, setCurrentPage] = useState(1); @@ -28,6 +31,8 @@ export default function Prompts() { creator: "João Silva", lastModified: "2 dias atrás", status: "published" as const, + version: "2.1.0", + systemPrompt: "Você é Clara, assistente de atendimento ao cliente...", }, { id: 2, @@ -35,6 +40,8 @@ export default function Prompts() { creator: "Maria Santos", lastModified: "5 dias atrás", status: "published" as const, + version: "1.5.0", + systemPrompt: "Você é um assistente de vendas...", }, { id: 3, @@ -42,6 +49,8 @@ export default function Prompts() { creator: "Pedro Costa", lastModified: "1 semana atrás", status: "draft" as const, + version: "1.0.0", + systemPrompt: "Você é um analista especializado...", }, { id: 4, @@ -49,6 +58,8 @@ export default function Prompts() { creator: "Ana Lima", lastModified: "3 dias atrás", status: "published" as const, + version: "1.2.1", + systemPrompt: "Você é um especialista em marketing...", }, { id: 5, @@ -56,6 +67,8 @@ export default function Prompts() { creator: "Carlos Mendes", lastModified: "4 dias atrás", status: "published" as const, + version: "2.0.0", + systemPrompt: "Você é um técnico de suporte...", }, { id: 6, @@ -63,6 +76,8 @@ export default function Prompts() { creator: "Fernanda Silva", lastModified: "6 dias atrás", status: "draft" as const, + version: "1.0.0", + systemPrompt: "Você é um guia de onboarding...", }, { id: 7, @@ -70,6 +85,8 @@ export default function Prompts() { creator: "Rafael Santos", lastModified: "1 dia atrás", status: "published" as const, + version: "1.1.0", + systemPrompt: "Você é responsável por follow-ups...", }, ]); @@ -95,6 +112,11 @@ export default function Prompts() { setCurrentPage(1); }; + const handleEditPrompt = (prompt: any) => { + setSelectedPrompt(prompt); + setIsEditDialogOpen(true); + }; + return ( @@ -139,7 +161,7 @@ export default function Prompts() { creator={prompt.creator} lastModified={prompt.lastModified} status={prompt.status} - onEdit={() => console.log("Edit", prompt.id)} + onEdit={() => handleEditPrompt(prompt)} onHistory={() => console.log("History", prompt.id)} onTest={() => console.log("Test", prompt.id)} onDuplicate={() => console.log("Duplicate", prompt.id)} @@ -206,6 +228,12 @@ export default function Prompts() { open={isCreateDialogOpen} onOpenChange={setIsCreateDialogOpen} /> + + ); }
{getVersionDescription()}