"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 (
);
}
// 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();