Create HGTX PromptLab UI

This commit is contained in:
gpt-engineer-app[bot]
2025-10-29 12:06:30 +00:00
parent d712cc7bb5
commit 6efb71b59b
13 changed files with 784 additions and 59 deletions
+48
View File
@@ -0,0 +1,48 @@
import { Bot, ExternalLink } from "lucide-react";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
interface AgentCardProps {
name: string;
description: string;
promptName?: string;
status: "active" | "inactive";
onLinkPrompt: () => void;
}
export function AgentCard({ name, description, promptName, status, onLinkPrompt }: AgentCardProps) {
return (
<Card className="p-6 hover:shadow-hover transition-all duration-200 animate-fade-in">
<div className="flex items-start justify-between mb-4">
<div className="flex items-center gap-3">
<div className="h-12 w-12 rounded-lg bg-primary/10 flex items-center justify-center">
<Bot className="h-6 w-6 text-primary" />
</div>
<div>
<h3 className="font-semibold text-foreground">{name}</h3>
<Badge variant={status === "active" ? "default" : "secondary"} className="mt-1">
{status === "active" ? "Ativo" : "Inativo"}
</Badge>
</div>
</div>
</div>
<p className="text-sm text-muted-foreground mb-4">{description}</p>
{promptName ? (
<div className="flex items-center justify-between p-3 bg-muted rounded-lg">
<div>
<p className="text-xs text-muted-foreground">Prompt vinculado</p>
<p className="text-sm font-medium text-foreground">{promptName}</p>
</div>
<ExternalLink className="h-4 w-4 text-muted-foreground" />
</div>
) : (
<Button onClick={onLinkPrompt} variant="outline" className="w-full">
Vincular Prompt
</Button>
)}
</Card>
);
}
+16
View File
@@ -0,0 +1,16 @@
import { SidebarProvider } from "@/components/ui/sidebar";
import { AppSidebar } from "./AppSidebar";
import { Outlet } from "react-router-dom";
export function AppLayout() {
return (
<SidebarProvider>
<div className="min-h-screen flex w-full bg-background">
<AppSidebar />
<main className="flex-1 p-6 lg:p-8">
<Outlet />
</main>
</div>
</SidebarProvider>
);
}
+77
View File
@@ -0,0 +1,77 @@
import { NavLink } from "react-router-dom";
import {
Bot,
FileText,
TestTube,
History,
Link,
} from "lucide-react";
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarHeader,
} from "@/components/ui/sidebar";
const menuItems = [
{ title: "Agentes", url: "/", icon: Bot },
{ title: "Prompts", url: "/prompts", icon: FileText },
{ title: "Testar Prompt", url: "/test", icon: TestTube },
{ title: "Histórico", url: "/history", icon: History },
{ title: "Vincular", url: "/link", icon: Link },
];
export function AppSidebar() {
return (
<Sidebar className="border-r border-border">
<SidebarHeader className="border-b border-border px-6 py-4">
<div className="flex items-center gap-2">
<div className="h-8 w-8 rounded-lg bg-primary flex items-center justify-center">
<Bot className="h-5 w-5 text-primary-foreground" />
</div>
<div>
<h1 className="text-lg font-semibold text-foreground">HGTX</h1>
<p className="text-xs text-muted-foreground">PromptLab</p>
</div>
</div>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel className="text-xs font-medium text-muted-foreground px-3">
Navegação
</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{menuItems.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<NavLink
to={item.url}
end
className={({ isActive }) =>
`flex items-center gap-3 px-3 py-2 rounded-md transition-colors ${
isActive
? "bg-primary text-primary-foreground font-medium"
: "text-foreground hover:bg-muted"
}`
}
>
<item.icon className="h-4 w-4" />
<span>{item.title}</span>
</NavLink>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
);
}
+63
View File
@@ -0,0 +1,63 @@
import { FileText, Edit, History, Copy, TestTube } from "lucide-react";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
interface PromptCardProps {
title: string;
creator: string;
lastModified: string;
status: "draft" | "published";
onEdit: () => void;
onHistory: () => void;
onTest: () => void;
onDuplicate: () => void;
}
export function PromptCard({
title,
creator,
lastModified,
status,
onEdit,
onHistory,
onTest,
onDuplicate,
}: PromptCardProps) {
return (
<Card className="p-5 hover:shadow-hover transition-all duration-200 animate-fade-in">
<div className="flex items-start justify-between mb-4">
<div className="flex items-center gap-3">
<div className="h-10 w-10 rounded-lg bg-accent/10 flex items-center justify-center">
<FileText className="h-5 w-5 text-accent" />
</div>
<div>
<h3 className="font-semibold text-foreground">{title}</h3>
<p className="text-xs text-muted-foreground mt-0.5">
por {creator} {lastModified}
</p>
</div>
</div>
<Badge variant={status === "published" ? "default" : "secondary"}>
{status === "published" ? "Publicado" : "Rascunho"}
</Badge>
</div>
<div className="flex items-center gap-2">
<Button onClick={onEdit} variant="outline" size="sm" className="flex-1">
<Edit className="h-4 w-4 mr-2" />
Editar
</Button>
<Button onClick={onHistory} variant="outline" size="sm">
<History className="h-4 w-4" />
</Button>
<Button onClick={onTest} variant="outline" size="sm">
<TestTube className="h-4 w-4" />
</Button>
<Button onClick={onDuplicate} variant="outline" size="sm">
<Copy className="h-4 w-4" />
</Button>
</div>
</Card>
);
}