import { useTranslation } from '../../i18n'
import type { NormalizedSkill } from '../../types/market'
import { InstallStateBadge } from './InstallStateBadge'
import { SecurityBadge } from './SecurityBadge'
import { SkillAvatar } from './SkillAvatar'
function formatCount(value: number): string {
if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`
if (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`
return String(value)
}
const MAX_VISIBLE_TAGS = 3
export function SkillCard({
skill,
onOpen,
onInstall,
installing,
}: {
skill: NormalizedSkill
onOpen: (id: string) => void
onInstall?: (id: string) => void
installing?: boolean
}) {
const t = useTranslation()
const extraTags = Math.max(0, skill.tags.length - MAX_VISIBLE_TAGS)
const showInstallButton = Boolean(onInstall) && skill.installState === 'installable'
return (
onOpen(skill.id)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
onOpen(skill.id)
}
}}
>
{skill.name}
{skill.version && (
v{skill.version}
)}
{t(`market.source.${skill.source}`)}
{skill.author.handle && (
{t('market.card.by', { author: skill.author.displayName || skill.author.handle })}
)}
{skill.summary || t('market.detail.noDescription')}
{skill.tags.length > 0 && (
{skill.tags.slice(0, MAX_VISIBLE_TAGS).map((tag) => (
{tag}
))}
{extraTags > 0 && (
{t('market.card.moreTags', { count: String(extraTags) })}
)}
)}
{/* The quick-install button already communicates "installable" — skip the badge when the button renders. */}
{!(skill.installState === 'installable' && showInstallButton) && (
)}
download
{formatCount(skill.stats.downloads)}
{typeof skill.stats.stars === 'number' && skill.stats.stars > 0 && (
star
{formatCount(skill.stats.stars)}
)}
{showInstallButton && (
)}
)
}