Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
'use client';
|
|
|
|
import { cn } from '@/lib/cn';
|
|
import type { Task } from '@/lib/types';
|
|
|
|
interface TaskCardProps {
|
|
task: Task;
|
|
onClick: (task: Task) => void;
|
|
}
|
|
|
|
const priorityColors: Record<string, string> = {
|
|
critical: 'text-error',
|
|
high: 'text-warning',
|
|
medium: 'text-blue-400',
|
|
low: 'text-text-muted',
|
|
};
|
|
|
|
const statusBadgeColors: Record<string, string> = {
|
|
'not-started': 'bg-gray-600/20 text-gray-300',
|
|
'in-progress': 'bg-blue-600/20 text-blue-400',
|
|
blocked: 'bg-error/20 text-error',
|
|
done: 'bg-success/20 text-success',
|
|
cancelled: 'bg-gray-600/20 text-gray-500',
|
|
};
|
|
|
|
export function TaskCard({ task, onClick }: TaskCardProps): React.ReactElement {
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={() => onClick(task)}
|
|
className="w-full rounded-lg border border-surface-border bg-surface-card p-3 text-left transition-colors hover:border-gray-500"
|
|
>
|
|
<div className="flex items-start justify-between gap-2">
|
|
<span className="text-sm font-medium text-text-primary">{task.title}</span>
|
|
<span className={cn('text-xs', priorityColors[task.priority])}>{task.priority}</span>
|
|
</div>
|
|
{task.description && (
|
|
<p className="mt-1 line-clamp-2 text-xs text-text-muted">{task.description}</p>
|
|
)}
|
|
<div className="mt-2 flex items-center gap-2">
|
|
<span
|
|
className={cn(
|
|
'rounded-full px-2 py-0.5 text-xs',
|
|
statusBadgeColors[task.status] ?? 'bg-gray-600/20 text-gray-400',
|
|
)}
|
|
>
|
|
{task.status}
|
|
</span>
|
|
{task.dueDate && (
|
|
<span className="text-xs text-text-muted">
|
|
{new Date(task.dueDate).toLocaleDateString()}
|
|
</span>
|
|
)}
|
|
</div>
|
|
</button>
|
|
);
|
|
}
|