import { formatBytes } from '~/lib/util' import DynamicIcon, { DynamicIconName } from './DynamicIcon' import type { CategoryWithStatus, SpecTier } from '../../types/collections' import classNames from 'classnames' import { IconChevronRight, IconCircleCheck, IconLoader2 } from '@tabler/icons-react' export interface CategoryCardProps { category: CategoryWithStatus selectedTier?: SpecTier | null onClick?: (category: CategoryWithStatus) => void } const CategoryCard: React.FC = ({ category, selectedTier, onClick }) => { // Calculate total size range across all tiers const getTierTotalSize = (tier: SpecTier, allTiers: SpecTier[]): number => { let total = tier.resources.reduce((acc, r) => acc + r.size_mb * 1024 * 1024, 0) // Add included tier sizes recursively if (tier.includesTier) { const includedTier = allTiers.find(t => t.slug === tier.includesTier) if (includedTier) { total += getTierTotalSize(includedTier, allTiers) } } return total } const minSize = getTierTotalSize(category.tiers[0], category.tiers) const maxSize = getTierTotalSize(category.tiers[category.tiers.length - 1], category.tiers) // Priority order for the prominent corner badge + lime border: // 1. selectedTier — in-session wizard pick (highest priority, reflects // what the user is editing right now) // 2. downloadingTierSlug — backend-derived from in-flight downloads, so // the card shows the user's intent immediately after Submit, before // any single file has finished downloading // 3. installedTierSlug — fully on disk const downloadingTier = !selectedTier && category.downloadingTierSlug ? category.tiers.find((t) => t.slug === category.downloadingTierSlug) : null const installedTier = !selectedTier && !downloadingTier && category.installedTierSlug ? category.tiers.find((t) => t.slug === category.installedTierSlug) : null const badgeTier = selectedTier || downloadingTier || installedTier const badgeStatus: 'selected' | 'downloading' | 'installed' | null = selectedTier ? 'selected' : downloadingTier ? 'downloading' : installedTier ? 'installed' : null const highlightedTierSlug = badgeTier?.slug return (
onClick?.(category)} >

{category.name}

{badgeTier ? (
{badgeStatus === 'downloading' ? ( ) : ( )} {badgeTier.name} {badgeStatus === 'downloading' && (category.downloadingTierIndexing ? ' (indexing)' : ' (downloading)')}
) : ( )}

{category.description}

{category.tiers.length} tiers available {!highlightedTierSlug && ( - Click to choose )}

{category.tiers.map((tier) => { const isInstalled = tier.slug === highlightedTierSlug return ( {tier.name} ) })}

Size: {formatBytes(minSize, 1)} - {formatBytes(maxSize, 1)}

) } export default CategoryCard