import React, { useState, useEffect } from 'react'; import { supabase } from '../services/supabase'; import { Star, Download, Search, Users } from 'lucide-react'; import { motion } from 'framer-motion'; interface AgentTemplate { id: string; name: string; role: string; model: string; api_provider: string; system_prompt: string; category: string; description: string; is_featured: boolean; team_id?: string; is_public: boolean; teams?: { name: string }; } const Marketplace: React.FC = () => { const [templates, setTemplates] = useState([]); const [search, setSearch] = useState(''); const [loading, setLoading] = useState(true); const [deployingId, setDeployingId] = useState(null); const [message, setMessage] = useState(null); const [error, setError] = useState(null); const [activeFilter, setActiveFilter] = useState<'all' | 'public' | 'team'>('all'); useEffect(() => { const fetchTemplates = async () => { setLoading(true); setError(null); const { data, error: templateError } = await supabase .from('agent_templates') .select(` *, teams:team_id(name) `) .order('category', { ascending: true }) .order('name', { ascending: true }); if (templateError) { setError(templateError.message); } else { setTemplates(data ?? []); } setLoading(false); }; fetchTemplates(); }, []); const handleDeploy = async (template: AgentTemplate) => { setMessage(null); setError(null); setDeployingId(template.id); const { data: userData } = await supabase.auth.getUser(); if (!userData.user) { setError('Please log in to deploy agents.'); setDeployingId(null); return; } try { const { data: existingAgent, error: lookupError } = await supabase .from('agents') .select('id') .eq('user_id', userData.user.id) .eq('name', template.name) .eq('role', template.role) .limit(1) .maybeSingle(); if (lookupError) throw lookupError; if (existingAgent) { setMessage(`${template.name} is already in your agent fleet.`); return; } const { error: insertError } = await supabase.from('agents').insert({ user_id: userData.user.id, name: template.name, role: template.role, model: template.model, api_provider: template.api_provider, system_prompt: template.system_prompt }); if (insertError) throw insertError; setMessage(`${template.name} has been added to your agent fleet.`); } catch (e: any) { setError(`Failed to deploy agent: ${e.message || 'Unknown error'}`); } finally { setDeployingId(null); } }; const filteredTemplates = templates.filter(t => { const matchesSearch = t.name.toLowerCase().includes(search.toLowerCase()) || t.category.toLowerCase().includes(search.toLowerCase()); if (activeFilter === 'public') return matchesSearch && t.is_public; if (activeFilter === 'team') return matchesSearch && t.team_id !== null; return matchesSearch; }); return (

Agent Marketplace

Deploy pre-configured expert agents to your projects.

setSearch(e.target.value)} style={{ width: '100%', padding: '0.8rem 1rem 0.8rem 2.5rem', background: 'rgba(255,255,255,0.05)', border: '1px solid var(--glass-border)', borderRadius: 'var(--radius-md)', color: 'white', outline: 'none' }} />
{error &&
{error}
} {message &&
{message}
} {loading &&
Loading marketplace templates...
} {!loading && filteredTemplates.length === 0 && (

No templates found

{search ? 'Try a different search term.' : 'Apply database/marketplace.sql in Supabase to seed marketplace templates.'}

)}
{filteredTemplates.map((template, i) => (
{template.category} {template.team_id && ( {template.teams?.name || 'Team'} )}
{template.is_featured && }

{template.name}

{template.description}

{template.model}
))}
); }; export default Marketplace;