'use client'; import React, { useState, useMemo, useEffect } from 'react'; import dynamic from 'next/dynamic'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuSeparator } from '@/components/ui/dropdown-menu'; import { Bot, Plus, Star, Search, Filter, ChevronDown } from 'lucide-react'; import { cn } from '@/lib/utils'; import { AgentCard } from './agent-card'; import type { EnhancedAgent, AgentCategory } from '@/services/agents-enhanced'; // Dynamically import configuration panel for better performance const AgentConfigurationPanel = dynamic( () => import('./agent-configuration-panel').then(mod => ({ default: mod.AgentConfigurationPanel })), { ssr: false } ); interface AgentGalleryProps { agents: EnhancedAgent[]; onSelectAgent: (agent: EnhancedAgent) => void; onCreateAgent?: (agentData: any) => Promise; onEditAgent?: (agentData: any) => Promise; onDeleteAgent?: (agentId: string) => Promise; onDuplicateAgent?: (agent: EnhancedAgent) => Promise; onViewHistory?: (agent: EnhancedAgent) => void; className?: string; hideHeader?: boolean; triggerCreate?: boolean; onTriggerComplete?: () => void; } type SortBy = 'name' | 'created_at' | 'usage_count' | 'average_rating'; export function AgentGallery({ agents, onSelectAgent, onCreateAgent, onEditAgent, onDeleteAgent, onDuplicateAgent, onViewHistory, className, hideHeader = false, triggerCreate = false, onTriggerComplete }: AgentGalleryProps) { // Removed showCreateModal state - using only showConfigPanel const [showConfigPanel, setShowConfigPanel] = useState(false); const [isCreating, setIsCreating] = useState(false); const [editingAgent, setEditingAgent] = useState(null); // Search and filter state const [searchQuery, setSearchQuery] = useState(''); const [selectedCategory, setSelectedCategory] = useState('all'); const [selectedTag, setSelectedTag] = useState('all'); const [selectedCreator, setSelectedCreator] = useState('all'); const [sortBy, setSortBy] = useState('created_at'); // Handle external trigger to create agent useEffect(() => { if (triggerCreate) { handleOpenCreateAgent(); onTriggerComplete?.(); } }, [triggerCreate]); // Extract unique categories, tags, and creators for filters const { categories, tags, creators } = useMemo(() => { const categorySet = new Set(); const tagSet = new Set(); const creatorSet = new Set(); agents.forEach(agent => { if (agent.category) categorySet.add(agent.category); agent.tags?.forEach(tag => tagSet.add(tag)); if (agent.owner_name) creatorSet.add(agent.owner_name); }); return { categories: Array.from(categorySet).sort(), tags: Array.from(tagSet).sort(), creators: Array.from(creatorSet).sort() }; }, [agents]); // Filter and sort agents const filteredAndSortedAgents = useMemo(() => { let filtered = agents.filter(agent => { // Search filter const matchesSearch = !searchQuery || agent.name.toLowerCase().includes(searchQuery.toLowerCase()) || agent.description?.toLowerCase().includes(searchQuery.toLowerCase()) || agent.tags?.some(tag => tag.toLowerCase().includes(searchQuery.toLowerCase())); // Category filter const matchesCategory = selectedCategory === 'all' || agent.category === selectedCategory; // Tag filter const matchesTag = selectedTag === 'all' || agent.tags?.includes(selectedTag); // Creator filter const matchesCreator = selectedCreator === 'all' || agent.owner_name === selectedCreator; return matchesSearch && matchesCategory && matchesTag && matchesCreator; }); // Sort agents filtered.sort((a, b) => { switch (sortBy) { case 'name': return a.name.localeCompare(b.name); case 'usage_count': return (b.usage_count || 0) - (a.usage_count || 0); case 'average_rating': return (b.average_rating || 0) - (a.average_rating || 0); case 'created_at': default: return new Date(b.created_at || 0).getTime() - new Date(a.created_at || 0).getTime(); } }); return filtered; }, [agents, searchQuery, selectedCategory, selectedTag, selectedCreator, sortBy]); const handleCreateAgent = async (agentData: any) => { if (!onCreateAgent) return; try { setIsCreating(true); await onCreateAgent(agentData); setShowConfigPanel(false); } catch (error) { console.error('Failed to create agent:', error); } finally { setIsCreating(false); } }; const handleOpenCreateAgent = () => { console.log('🔧 Create Agent button clicked'); setEditingAgent(null); setShowConfigPanel(true); console.log('🔧 showConfigPanel set to:', true); }; const handleSaveAgent = async (agentData: Partial) => { if (editingAgent) { // Edit existing agent - merge with original agent data and include ID const updateData = { ...agentData, id: editingAgent.id // Ensure ID is included for update }; await onEditAgent?.(updateData); } else { // Create new agent await onCreateAgent?.(agentData); } setShowConfigPanel(false); setEditingAgent(null); }; const handleAgentAction = async (action: string, agent: EnhancedAgent, event: React.MouseEvent) => { event.stopPropagation(); switch (action) { case 'edit': setEditingAgent(agent); setShowConfigPanel(true); break; case 'delete': if (confirm(`Are you sure you want to archive "${agent.name}"? This will hide it from view but preserve it for audit trail purposes.`)) { await onDeleteAgent?.(agent.id); } break; } }; if (filteredAndSortedAgents.length === 0 && agents.length === 0) { return (
{/* Search and Filters - show even when no agents */}
{/* Search */}
setSearchQuery(value)} className="pl-10" clearable />
{/* Filters */}
{/* Empty State */}

No agents yet

Create your first AI agent to get started with intelligent conversations and automation. Use the "Create Agent" button in the top right corner.

{/* Configuration Panel - unified creation interface */} {console.log('🔧 Empty state - Rendering AgentConfigurationPanel with showConfigPanel:', showConfigPanel)} { console.log('🔧 Empty state - Closing configuration panel'); setShowConfigPanel(false); setEditingAgent(null); }} onSave={handleSaveAgent} mode={editingAgent ? 'edit' : 'create'} />
); } return (
{/* Header - only show if not hidden */} {!hideHeader && (

Your Agents

{filteredAndSortedAgents.length} of {agents.length} agents

)} {/* Search and Filters */}
{/* Search */}
setSearchQuery(value)} className="pl-10" clearable />
{/* Filters */}
{/* No Results */} {filteredAndSortedAgents.length === 0 && agents.length > 0 && (

No agents found

Try adjusting your search or filter criteria.

)} {/* Agent List */}
{filteredAndSortedAgents.map((agent) => ( { setEditingAgent(agent); setShowConfigPanel(true); }} onDelete={(agent) => { if (confirm(`Are you sure you want to archive "${agent.name}"?`)) { onDeleteAgent?.(agent.id); } }} canExport={agent.is_owner || false} /> ))}
{/* Agent Configuration Panel - unified creation and editing interface */} {console.log('🔧 Rendering AgentConfigurationPanel with showConfigPanel:', showConfigPanel)} { console.log('🔧 Closing configuration panel'); setShowConfigPanel(false); setEditingAgent(null); }} onSave={handleSaveAgent} mode={editingAgent ? 'edit' : 'create'} />
); }