import React, { useState } from "react"; import { motion } from "framer-motion"; import { ArrowLeft, Save, Loader2, ChevronDown } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Toast, ToastContainer } from "@/components/ui/toast"; import { useTranslation } from "@/hooks/useTranslation"; import { api, type Agent } from "@/lib/api"; import { cn } from "@/lib/utils"; import MDEditor from "@uiw/react-md-editor"; import { type AgentIconName } from "./CCAgents"; import { IconPicker, ICON_MAP } from "./IconPicker"; interface CreateAgentProps { /** * Optional agent to edit (if provided, component is in edit mode) */ agent?: Agent; /** * Callback to go back to the agents list */ onBack: () => void; /** * Callback when agent is created/updated */ onAgentCreated: () => void; /** * Optional className for styling */ className?: string; } /** * CreateAgent component for creating or editing a CC agent * * @example * setView('list')} onAgentCreated={handleCreated} /> */ export const CreateAgent: React.FC = ({ agent, onBack, onAgentCreated, className, }) => { const { t } = useTranslation(); const [name, setName] = useState(agent?.name || ""); const [selectedIcon, setSelectedIcon] = useState((agent?.icon as AgentIconName) || "bot"); const [systemPrompt, setSystemPrompt] = useState(agent?.system_prompt || ""); const [defaultTask, setDefaultTask] = useState(agent?.default_task || ""); const [model, setModel] = useState(agent?.model || "sonnet"); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null); const [showIconPicker, setShowIconPicker] = useState(false); const isEditMode = !!agent; const handleSave = async () => { if (!name.trim()) { setError(t('agents.agentNameRequired')); return; } if (!systemPrompt.trim()) { setError(t('agents.systemPromptRequired')); return; } try { setSaving(true); setError(null); if (isEditMode && agent.id) { await api.updateAgent( agent.id, name, selectedIcon, systemPrompt, defaultTask || undefined, model ); } else { await api.createAgent( name, selectedIcon, systemPrompt, defaultTask || undefined, model ); } onAgentCreated(); } catch (err) { console.error("Failed to save agent:", err); setError(isEditMode ? t('agents.updateFailed') : t('agents.createFailed')); setToast({ message: isEditMode ? t('agents.updateFailed') : t('agents.createFailed'), type: "error" }); } finally { setSaving(false); } }; const handleBack = () => { if ((name !== (agent?.name || "") || selectedIcon !== (agent?.icon || "bot") || systemPrompt !== (agent?.system_prompt || "") || defaultTask !== (agent?.default_task || "") || model !== (agent?.model || "sonnet")) && !confirm(t('messages.unsavedChanges'))) { return; } onBack(); }; return (
{/* Header */}

{isEditMode ? t('agents.editAgent') : t('agents.createAgent')}

{isEditMode ? t('agents.updateAgentDescription') : t('agents.createAgentDescription')}

{/* Error display */} {error && ( {error} )} {/* Form */}
{/* Basic Information */}

{t('agents.basicInformation')}

{/* Name and Icon */}
setName(e.target.value)} placeholder={t('placeholders.enterAgentName')} required />
setShowIconPicker(true)} className="h-10 px-3 py-2 bg-background border border-input rounded-md cursor-pointer hover:bg-accent hover:text-accent-foreground transition-colors flex items-center justify-between" >
{(() => { const Icon = ICON_MAP[selectedIcon] || ICON_MAP.bot; return ( <> {selectedIcon} ); })()}
{/* Model Selection */}
{/* Default Task */}
setDefaultTask(e.target.value)} className="max-w-md" />

{t('agents.defaultTaskDescription')}

{/* System Prompt Editor */}

{t('agents.systemPromptDescription')}

setSystemPrompt(val || "")} preview="edit" height={400} visibleDragbar={false} />
{/* Toast Notification */} {toast && ( setToast(null)} /> )} {/* Icon Picker Dialog */} { setSelectedIcon(iconName as AgentIconName); setShowIconPicker(false); }} isOpen={showIconPicker} onClose={() => setShowIconPicker(false)} />
); };