"use client"; import React from "react"; import type { Task } from "@mosaic/shared"; import { TaskPriority } from "@mosaic/shared"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { Calendar, Flag, User } from "lucide-react"; import { format } from "date-fns"; interface TaskCardProps { task: Task & { assignee?: { name: string; image?: string | null } }; } const priorityConfig = { [TaskPriority.HIGH]: { label: "High", className: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400", }, [TaskPriority.MEDIUM]: { label: "Medium", className: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400", }, [TaskPriority.LOW]: { label: "Low", className: "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400", }, }; /** * Generate initials from a name (e.g., "John Doe" -> "JD") */ function getInitials(name: string): string { return name .split(" ") .map((part) => part[0]) .join("") .toUpperCase() .slice(0, 2); } /** * Task Card component for Kanban board * * Displays: * - Task title * - Priority badge * - Assignee avatar (if assigned) * - Due date (if set) */ export function TaskCard({ task }: TaskCardProps): React.ReactElement { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: task.id, }); const style = { transform: CSS.Transform.toString(transform), transition, }; const isOverdue = task.dueDate && new Date(task.dueDate) < new Date() && task.status !== "COMPLETED"; const isDueSoon = task.dueDate && !isOverdue && new Date(task.dueDate).getTime() - new Date().getTime() < 3 * 24 * 60 * 60 * 1000; // 3 days const priorityInfo = priorityConfig[task.priority]; return (
{/* Task Title */}

{task.title}

{/* Task Metadata */}
{/* Priority Badge */} {/* Due Date */} {task.dueDate && ( {format(new Date(task.dueDate), "MMM d")} )}
{/* Assignee Avatar */} {task.assignee && (
{task.assignee.image ? ( {task.assignee.name} ) : (
{getInitials(task.assignee.name)}
)} {task.assignee.name}
)} {/* Fallback for unassigned tasks */} {!task.assignee && task.assigneeId && (
Assigned
)}
); }