/** * ProjectCard Component * * Displays a project card for the projects grid view. * Shows project status, progress, metrics, and quick info. * * @see Issue #54 */ 'use client'; import { Bot, CircleDot, Clock, MoreVertical, Archive, Play, Pause } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Skeleton } from '@/components/ui/skeleton'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { cn } from '@/lib/utils'; import { ProjectStatusBadge } from './StatusBadge'; import { ProgressBar } from './ProgressBar'; import type { ProjectListItem } from '@/lib/api/hooks/useProjects'; export interface ProjectCardProps { /** Project data */ project: ProjectListItem; /** Called when card is clicked */ onClick?: () => void; /** Called when action menu item is selected */ onAction?: (action: 'archive' | 'pause' | 'resume' | 'delete') => void; /** Additional CSS classes */ className?: string; } /** * Complexity indicator dots */ function ComplexityIndicator({ complexity }: { complexity: 'low' | 'medium' | 'high' }) { const levels = { low: 1, medium: 2, high: 3 }; const level = levels[complexity]; return (
{[1, 2, 3].map((i) => (
))}
); } /** * Loading skeleton for project cards */ export function ProjectCardSkeleton() { return (
); } export function ProjectCard({ project, onClick, onAction, className }: ProjectCardProps) { return ( { /* istanbul ignore next -- keyboard handler */ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick?.(); } }} >
{onAction && ( e.stopPropagation()}> e.stopPropagation()}> {project.status === 'paused' ? ( onAction('resume')}> Resume Project ) : project.status === 'active' ? ( onAction('pause')}> Pause Project ) : null} onAction('archive')}> Archive Project onAction('delete')} > Delete Project )}
{project.name} {project.description && (

{project.description}

)}
{project.tags && project.tags.length > 0 && (
{project.tags.slice(0, 3).map((tag) => ( {tag} ))} {project.tags.length > 3 && ( +{project.tags.length - 3} )}
)}
{project.activeAgents} {project.openIssues}
{project.lastActivity}
); }