import { Check, Download, RotateCcw, Star } from "lucide-react"; import { Link } from "@/lib/router"; import { cn } from "@/lib/utils"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import type { SkillListItem } from "@/api/skillRegistry"; // TODO: hasUpdate detection requires backend enhancement — SkillListItem needs // a hasUpdate field or the UI needs to compare activeVersionId against latest version. // For now, hasUpdate is always passed as false from parent components. export interface SkillCardProps { skill: SkillListItem; isInstalled?: boolean; hasUpdate?: boolean; onInstall?: () => void; onUpdate?: () => void; onRollback?: () => void; onUninstall?: () => void; isLoading?: boolean; isReadOnly?: boolean; source?: "managed" | "native"; className?: string; compatibleAdapters?: string[]; } export function SkillCard({ skill, isInstalled = false, hasUpdate = false, onInstall, onUpdate, onRollback, onUninstall, isLoading = false, isReadOnly = false, source, className, compatibleAdapters, }: SkillCardProps) { return ( {/* Row 1: name link (primary visual anchor) + update badge + native badge */}
{skill.name}
{(isReadOnly || source === "native") && ( Native )} {hasUpdate && !isReadOnly && ( Update )}
{/* Row 2: description (2-line clamp) */} {skill.description && (

{skill.description}

)} {/* Row 2b: compatible adapters (Browse/Trending only) */} {compatibleAdapters && compatibleAdapters.length > 0 && (

Works with: {compatibleAdapters.join(", ")}

)} {/* Row 3: source badge + rating + actions (push right) */}
{skill.sourceId} {skill.averageRating != null && ( {skill.averageRating.toFixed(1)} )}
{!isReadOnly && isInstalled && onRollback && ( Rollback )} {!isReadOnly && !isInstalled && ( )} {!isReadOnly && isInstalled && hasUpdate && ( )} {isInstalled && !hasUpdate && ( )}
); }