"use client"; import { ColumnDef } from "@tanstack/react-table"; import { ArrowUpDown, MoreHorizontal, Eye, Pencil, Trash2, Clock, AlertTriangle, CheckCircle2 } from "lucide-react"; import Link from "next/link"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Checkbox } from "@/components/ui/checkbox"; import { Progress } from "@/components/ui/progress"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Task, TaskStatus, TaskPriority, TASK_STATUS_CONFIG, TASK_PRIORITY_CONFIG } from "@/types/task"; // Badge de estado function TaskStatusBadge({ status }: { status: TaskStatus }) { const config = TASK_STATUS_CONFIG[status]; return ( {status === '2' && } {config.label} ); } // Badge de prioridad function TaskPriorityBadge({ priority }: { priority: TaskPriority }) { const config = TASK_PRIORITY_CONFIG[priority]; if (priority === '0') { return null; } return ( {priority === '3' && } {config.label} ); } // Barra de progreso compacta function TaskProgress({ progress }: { progress: number }) { const getColorClass = (value: number) => { if (value >= 100) return '[&>div]:bg-green-500'; if (value >= 75) return '[&>div]:bg-blue-500'; if (value >= 50) return '[&>div]:bg-yellow-500'; return '[&>div]:bg-gray-400'; }; return (
{progress}%
); } // Formatear fecha function formatDate(dateString: string | null): string { if (!dateString) return '-'; return new Date(dateString).toLocaleDateString('es-ES', { day: '2-digit', month: 'short', }); } // Formatear horas function formatHours(hours: number): string { if (hours === 0) return '-'; return `${hours}h`; } // Interfaz para callbacks de acciones export interface TaskColumnCallbacks { onEdit?: (task: Task) => void; onDelete?: (task: Task) => void; } // Función para crear columnas con callbacks opcionales export function createTaskColumns(callbacks?: TaskColumnCallbacks): ColumnDef[] { return [ // Checkbox { id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label="Seleccionar todo" /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label="Seleccionar fila" /> ), enableSorting: false, enableHiding: false, }, // Título { accessorKey: "title", header: ({ column }) => ( ), cell: ({ row }) => (
{row.getValue("title")} {row.original.ref && (

{row.original.ref}

)}
), }, // Estado { accessorKey: "status", header: "Estado", cell: ({ row }) => , filterFn: (row, id, value) => value.includes(row.getValue(id)), }, // Prioridad { accessorKey: "priority", header: "Prioridad", cell: ({ row }) => , filterFn: (row, id, value) => value.includes(row.getValue(id)), }, // Progreso { accessorKey: "progress", header: ({ column }) => ( ), cell: ({ row }) => , }, // Horas { id: "hours", header: () => (
Horas
), cell: ({ row }) => (
{formatHours(row.original.workedHours)} {row.original.plannedHours > 0 && ( / {formatHours(row.original.plannedHours)} )}
), }, // Fecha límite { accessorKey: "endDate", header: ({ column }) => ( ), cell: ({ row }) => { const endDate = row.original.endDate || row.original.plannedEndDate; const isOverdue = endDate && new Date(endDate) < new Date() && row.original.status !== '2'; return ( {formatDate(endDate)} {isOverdue && } ); }, }, // Acciones { id: "actions", enableHiding: false, cell: ({ row }) => { const task = row.original; return ( Acciones Ver detalles callbacks?.onEdit?.(task)} disabled={!callbacks?.onEdit} > Editar Registrar tiempo callbacks?.onDelete?.(task)} disabled={!callbacks?.onDelete} > Eliminar ); }, }, ]; } // Columnas por defecto sin callbacks (para compatibilidad) export const taskColumns: ColumnDef[] = createTaskColumns();