ai-chatbot/components/agents/AgentPanelHeader.tsx
Your Name 2e21d1b274
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
feat: refresh agent workflow frontend
2026-03-17 23:40:42 +08:00

98 lines
3.4 KiB
TypeScript

"use client";
import { motion } from "framer-motion";
import { Plus, Search, Sparkles, Wand2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
interface AgentPanelHeaderProps {
title?: string;
description?: string;
searchValue: string;
onSearchChange: (value: string) => void;
searchPlaceholder?: string;
onCreateClick?: () => void;
createLabel?: string;
className?: string;
}
export function AgentPanelHeader({
title = "智能体",
description = "选择模式后,工作台会自动加载对应槽位和生成能力",
searchValue,
onSearchChange,
searchPlaceholder = "搜索智能体...",
onCreateClick,
createLabel = "新建智能体",
className,
}: AgentPanelHeaderProps) {
return (
<div className={cn("border-b border-slate-200/60 bg-white/50 p-5 dark:border-slate-800/60 dark:bg-slate-950/50", className)}>
{/* 标题区域 */}
<div className="mb-4 flex items-start justify-between gap-4">
<div>
<motion.div
className="flex items-center gap-2"
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.3 }}
>
<div className="flex h-8 w-8 items-center justify-center rounded-xl bg-gradient-to-br from-indigo-500 to-violet-600 text-white shadow-lg shadow-indigo-500/20">
<Wand2 className="h-4 w-4" />
</div>
<h2 className="text-lg font-semibold text-slate-900 dark:text-slate-100">
{title}
</h2>
</motion.div>
<motion.p
className="mt-1.5 text-xs leading-relaxed text-slate-500 dark:text-slate-400"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: 0.1 }}
>
{description}
</motion.p>
</div>
{onCreateClick && (
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3, delay: 0.15 }}
>
<Button
size="sm"
onClick={onCreateClick}
className="h-9 gap-1.5 rounded-xl bg-slate-900 px-4 text-xs font-medium text-white shadow-md shadow-slate-900/10 transition-all hover:bg-slate-800 hover:shadow-lg hover:shadow-slate-900/20 dark:bg-indigo-600 dark:hover:bg-indigo-500"
>
<Plus className="h-3.5 w-3.5" />
{createLabel}
</Button>
</motion.div>
)}
</div>
{/* 搜索框 */}
<motion.div
className="relative"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3, delay: 0.2 }}
>
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
<Input
placeholder={searchPlaceholder}
value={searchValue}
onChange={(event) => onSearchChange(event.target.value)}
className={cn(
"h-10 rounded-xl border-slate-200/60 bg-white pl-10 text-sm",
"placeholder:text-slate-400",
"focus:border-indigo-500/50 focus:ring-indigo-500/20",
"dark:border-slate-800/60 dark:bg-slate-900/50"
)}
/>
</motion.div>
</div>
);
}