// AGENTFORGE-IA — Marketplace
const Marketplace = ({ data, openAgent, openCategory, activeCategory, setActiveCategory }) => {
const [q, setQ] = React.useState('');
const [sort, setSort] = React.useState('popular');
const cats = Array.isArray(data?.categories) ? data.categories : [];
const agents = Array.isArray(data?.agents) ? data.agents : [];
const resultsRef = React.useRef(null);
const selectCategory = (id) => {
setActiveCategory(id);
setTimeout(() => {
if (resultsRef.current) {
resultsRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}, 60);
};
// Contadores reales por categoría
const catCounts = React.useMemo(() => {
const counts = {};
agents.forEach(a => { counts[a.cat] = (counts[a.cat] || 0) + 1; });
return counts;
}, [agents]);
const featured = React.useMemo(() => {
if (agents.length === 0) {
return null;
}
return [...agents]
.sort((a, b) => (Number(b.runs) || 0) - (Number(a.runs) || 0))[0] || null;
}, [agents]);
const filtered = agents.filter(a => {
if (activeCategory && activeCategory !== 'all' && a.cat !== activeCategory) return false;
const name = (a.name || '').toLowerCase();
const tagline = (a.tagline || '').toLowerCase();
if (q && !(name.includes(q.toLowerCase()) || tagline.includes(q.toLowerCase()))) return false;
return true;
}).sort((a,b) => sort === 'popular'
? (Number(b.runs) || 0) - (Number(a.runs) || 0)
: sort === 'rating'
? (Number(b.rating) || 0) - (Number(a.rating) || 0)
: (Number(b.runs) || 0) - (Number(a.runs) || 0));
const totalAgents = agents.length;
const visibleCats = cats.filter(c => (catCounts[c.id] || 0) > 0);
return (
Marketplace
explorar › {totalAgents} agentes · {visibleCats.length} categorías
Explorar por categoría
·
{totalAgents} agentes en {visibleCats.length} categorías
{visibleCats.map(c => (
))}
Destacado esta semana
{featured ? (
openAgent(featured.id)}>
ELECCIÓN DEL EDITOR
investigación
{featured.name || 'Agente destacado'}
{featured.tagline || 'Agente recomendado por actividad y adopción.'} Planificación multietapa, fuentes recursivas y citas trazables.
{(Math.max(0, Number(featured.runs) || 0)/1000).toFixed(0)} k ejecuciones
{Number(featured.rating || 0).toString().replace('.', ',')} ({Number(featured.reviews) || 0})
{featured.author || 'Forge Labs'}
web.search
arxiv.fetch
memo.synth
Investigación Profunda
) : (
Sin agente destacado
Todavía no hay agentes suficientes para destacar uno en esta sección.
)}
{activeCategory && activeCategory !== 'all' ? cats.find(c=>c.id===activeCategory)?.name : 'Agentes destacados'}
·
{filtered.length} resultados
{activeCategory && activeCategory !== 'all' && (
)}
{filtered.map(a =>
c.id === a.cat)} onOpen={() => openAgent(a.id)} />)}
);
};
function AgentCard({ a, cat, onOpen }) {
const tools = (Array.isArray(a.tools) ? a.tools : []).filter(t => !/slack|zendesk/i.test(String(t)));
const runs = Number(a.runs) || 0;
const rating = Number(a.rating) || 0;
const reviews = Number(a.reviews) || 0;
return (
{a.name}
{a.verified && }
{a.author} · {cat?.name}
{String(a.price || '').toLowerCase().includes('gratis') ? 'De pago' : a.price}
{a.tagline}
{tools.slice(0,3).map(t => {t})}
{tools.length > 3 && +{tools.length - 3}}
{runs > 999 ? (runs/1000).toFixed(0)+' k' : runs}
{rating.toString().replace('.', ',')}
{reviews}
);
}
window.Marketplace = Marketplace;