Jake Shore 96e52666c5 MCPEngine full sync — studio scaffold, factory v2, server updates, state.json — 2026-02-12
=== NEW ===
- studio/ — MCPEngine Studio scaffold (Next.js monorepo, build plan)
- docs/FACTORY-V2.md — Factory v2 architecture doc
- docs/CALENDLY_MCP_BUILD_SUMMARY.md — Calendly MCP build report

=== UPDATED SERVERS ===
- fieldedge: Added jobs-tools, UI build script, main entry update
- lightspeed: Updated main + server entry points
- squarespace: Added collection-browser + page-manager apps
- toast: Added main + server entry points

=== INFRA ===
- infra/command-center/state.json — Updated pipeline state
- infra/command-center/FACTORY-V2.md — Factory v2 operator playbook
2026-02-12 17:58:33 -05:00

106 lines
3.4 KiB
TypeScript

'use client';
import { useRouter } from 'next/navigation';
import { Wrench, LayoutGrid, GitFork, Star, BadgeCheck } from 'lucide-react';
import type { MarketplaceTemplate } from '@mcpengine/ai-pipeline/types';
const CATEGORY_COLORS: Record<string, string> = {
CRM: 'bg-blue-600',
eCommerce: 'bg-emerald-600',
HR: 'bg-violet-600',
Finance: 'bg-amber-600',
Marketing: 'bg-pink-600',
Support: 'bg-teal-600',
ProjectMgmt: 'bg-orange-600',
Scheduling: 'bg-cyan-600',
Analytics: 'bg-rose-600',
DevTools: 'bg-lime-600',
Social: 'bg-fuchsia-600',
Communication: 'bg-sky-600',
Storage: 'bg-indigo-600',
'AI/ML': 'bg-purple-600',
};
function getCategoryColor(category?: string): string {
return (category && CATEGORY_COLORS[category]) || 'bg-gray-600';
}
interface TemplateCardProps {
template: MarketplaceTemplate;
}
export function TemplateCard({ template }: TemplateCardProps) {
const router = useRouter();
return (
<div
onClick={() => router.push(`/marketplace/${template.id}`)}
className="
group relative flex flex-col rounded-xl border border-gray-800
bg-gray-900/80 p-5 cursor-pointer
transition-all duration-200
hover:scale-[1.02] hover:border-gray-600 hover:shadow-xl hover:shadow-indigo-900/10
"
>
{/* Official badge */}
{template.isOfficial && (
<div className="absolute top-3 right-3 flex items-center gap-1 text-xs font-medium
text-indigo-400 bg-indigo-500/10 px-2 py-0.5 rounded-full">
<BadgeCheck className="h-3.5 w-3.5" />
Official
</div>
)}
{/* Icon + name */}
<div className="flex items-start gap-3 mb-3">
<div
className={`
flex-shrink-0 w-10 h-10 rounded-lg flex items-center justify-center
text-white font-bold text-sm ${getCategoryColor(template.category)}
`}
>
{template.name.charAt(0).toUpperCase()}
</div>
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-gray-100 truncate group-hover:text-white transition-colors">
{template.name}
</h3>
<span className="text-xs text-gray-500">{template.category}</span>
</div>
</div>
{/* Description */}
<p className="text-sm text-gray-400 line-clamp-2 mb-4 flex-1">
{template.description || 'No description provided.'}
</p>
{/* Star rating placeholder */}
<div className="flex items-center gap-0.5 mb-3">
{[1, 2, 3, 4, 5].map((i) => (
<Star
key={i}
className={`h-3.5 w-3.5 ${i <= 4 ? 'text-amber-400 fill-amber-400' : 'text-gray-700'}`}
/>
))}
<span className="text-xs text-gray-500 ml-1.5">4.0</span>
</div>
{/* Bottom stats row */}
<div className="flex items-center gap-3 pt-3 border-t border-gray-800/60">
<span className="flex items-center gap-1 text-xs text-gray-500">
<Wrench className="h-3.5 w-3.5" />
{template.toolCount} tools
</span>
<span className="flex items-center gap-1 text-xs text-gray-500">
<LayoutGrid className="h-3.5 w-3.5" />
{template.appCount} apps
</span>
<span className="flex items-center gap-1 text-xs text-gray-500 ml-auto">
<GitFork className="h-3.5 w-3.5" />
{template.forkCount}
</span>
</div>
</div>
);
}