tool-card.tsx•3.68 kB
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { ArrowRight, Github, Code, Search, Bug, FileCode, BarChart3 } from "lucide-react";
interface Tool {
name: string;
description: string;
category?: string;
inputSchema: {
type: "object";
properties: Record<string, any>;
required?: string[];
};
}
interface ToolCardProps {
tool: Tool;
onClick: () => void;
}
const getToolIcon = (toolName: string) => {
if (toolName.includes('github') || toolName.includes('repo')) {
return Github;
} else if (toolName.includes('search')) {
return Search;
} else if (toolName.includes('issue') || toolName.includes('bug')) {
return Bug;
} else if (toolName.includes('file')) {
return FileCode;
} else if (toolName.includes('analyz') || toolName.includes('metric')) {
return BarChart3;
}
return Code;
};
const getToolColor = (toolName: string) => {
if (toolName.includes('github')) {
return 'from-purple-600/20 to-blue-600/20 group-hover:from-purple-600/30 group-hover:to-blue-600/30';
} else if (toolName.includes('search')) {
return 'from-blue-600/20 to-cyan-600/20 group-hover:from-blue-600/30 group-hover:to-cyan-600/30';
} else if (toolName.includes('issue')) {
return 'from-green-600/20 to-teal-600/20 group-hover:from-green-600/30 group-hover:to-teal-600/30';
} else if (toolName.includes('file')) {
return 'from-orange-600/20 to-red-600/20 group-hover:from-orange-600/30 group-hover:to-red-600/30';
}
return 'from-purple-600/20 to-blue-600/20 group-hover:from-purple-600/30 group-hover:to-blue-600/30';
};
const getIconColor = (toolName: string) => {
if (toolName.includes('github')) {
return 'text-purple-400';
} else if (toolName.includes('search')) {
return 'text-blue-400';
} else if (toolName.includes('issue')) {
return 'text-green-400';
} else if (toolName.includes('file')) {
return 'text-orange-400';
}
return 'text-purple-400';
};
export default function ToolCard({ tool, onClick }: ToolCardProps) {
const Icon = getToolIcon(tool.name);
const requiredParams = tool.inputSchema.required?.length || 0;
const totalParams = Object.keys(tool.inputSchema.properties || {}).length;
const hasRequiredParams = requiredParams > 0;
return (
<Card
className="tool-card cursor-pointer border-border hover:border-primary/50 transition-all duration-200 hover:shadow-xl hover:shadow-primary/10 group bg-card"
onClick={onClick}
>
<CardContent className="p-6">
<div className="flex items-start justify-between mb-4">
<div className={`w-12 h-12 bg-gradient-to-r ${getToolColor(tool.name)} rounded-lg flex items-center justify-center transition-colors`}>
<Icon className={`${getIconColor(tool.name)} h-6 w-6`} />
</div>
<Badge className="text-xs">
{tool.category}
</Badge>
</div>
<h4 className="text-lg font-semibold mb-2 group-hover:text-primary transition-colors">
{tool.name.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
</h4>
<p className="text-muted-foreground text-sm mb-4 line-clamp-2">
{tool.description}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center text-xs text-muted-foreground">
<span>{totalParams} parameter{totalParams !== 1 ? 's' : ''}</span>
</div>
<ArrowRight className="h-4 w-4 text-primary opacity-0 group-hover:opacity-100 transition-opacity" />
</div>
</CardContent>
</Card>
);
}