"use client"; import { useState, useMemo } from "react"; import { Search, X, Plus, ListTodo, CheckCircle2, Clock, AlertTriangle, LayoutGrid, List } from "lucide-react"; import Link from "next/link"; import { toast } from "sonner"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { DeleteConfirmationDialog } from "@/components/ui/delete-confirmation-dialog"; import { DataTable } from "@/components/projects/data-table"; import { createTaskColumns } from "./task-columns"; import { TaskFormSheet } from "@/components/task-form/task-form-sheet"; import { Task, TASK_STATUS_CONFIG, TASK_PRIORITY_CONFIG } from "@/types/task"; import { deleteTask } from "@/lib/tasksService"; interface TasksSectionProps { tasks: Task[]; projectId: number; isLoading?: boolean; onTaskCreated?: (task: Task) => void; onTaskUpdated?: (task: Task) => void; onTaskDeleted?: (taskId: number) => void; } // Tarjeta de tarea para vista grid function TaskCard({ task }: { task: Task }) { const statusConfig = TASK_STATUS_CONFIG[task.status]; const priorityConfig = TASK_PRIORITY_CONFIG[task.priority]; const isOverdue = (() => { const endDate = task.endDate || task.plannedEndDate; return endDate && new Date(endDate) < new Date() && task.status !== '2'; })(); return ( {/* Header */} {task.title} {task.ref && ( {task.ref} )} {task.priority !== '0' && ( {task.priority === '3' && } {priorityConfig.label} )} {/* Progreso */} Progreso {task.progress}% = 100 ? 'bg-green-500' : task.progress >= 50 ? 'bg-blue-500' : 'bg-gray-400' }`} style={{ width: `${task.progress}%` }} /> {/* Footer */} {task.status === '2' && } {statusConfig.label} {(task.endDate || task.plannedEndDate) && ( {new Date(task.endDate || task.plannedEndDate!).toLocaleDateString('es-ES', { day: '2-digit', month: 'short', })} {isOverdue && } )} ); } // Estado vacío function EmptyTasks({ onCreateClick }: { onCreateClick: () => void }) { return ( Sin tareas Este proyecto aún no tiene tareas asignadas. Crea la primera tarea para comenzar. Crear tarea ); } export function TasksSection({ tasks, projectId, isLoading, onTaskCreated, onTaskUpdated, onTaskDeleted }: TasksSectionProps) { const [searchValue, setSearchValue] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); const [priorityFilter, setPriorityFilter] = useState("all"); const [viewMode, setViewMode] = useState<"table" | "grid">("table"); const [isCreateSheetOpen, setIsCreateSheetOpen] = useState(false); const [isEditSheetOpen, setIsEditSheetOpen] = useState(false); const [taskToEdit, setTaskToEdit] = useState(null); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [taskToDelete, setTaskToDelete] = useState(null); const [isDeleting, setIsDeleting] = useState(false); // Handler para cuando se crea una tarea exitosamente const handleCreateSuccess = (task: Task) => { onTaskCreated?.(task); }; // Handler para cuando se edita una tarea exitosamente const handleEditSuccess = (task: Task) => { onTaskUpdated?.(task); setTaskToEdit(null); }; // Handler para abrir el sheet de edición const handleEditTask = (task: Task) => { setTaskToEdit(task); setIsEditSheetOpen(true); }; // Handler para abrir el diálogo de eliminación const handleDeleteTask = (task: Task) => { setTaskToDelete(task); setIsDeleteDialogOpen(true); }; // Handler para confirmar eliminación const handleConfirmDelete = async () => { if (!taskToDelete) return; setIsDeleting(true); try { await deleteTask(taskToDelete.id); onTaskDeleted?.(taskToDelete.id); setIsDeleteDialogOpen(false); setTaskToDelete(null); } catch (error) { console.error("Error deleting task:", error); toast.error("Error al eliminar la tarea", { description: "No se pudo eliminar la tarea. Inténtalo de nuevo.", }); } finally { setIsDeleting(false); } }; // Crear columnas con callbacks const columns = useMemo(() => createTaskColumns({ onEdit: handleEditTask, onDelete: handleDeleteTask, }), []); // Filtrar tareas const filteredTasks = useMemo(() => { let result = [...tasks]; // Búsqueda if (searchValue) { const search = searchValue.toLowerCase(); result = result.filter( (task) => task.title.toLowerCase().includes(search) || task.ref?.toLowerCase().includes(search) || task.description?.toLowerCase().includes(search) ); } // Filtro de estado if (statusFilter !== "all") { result = result.filter((task) => task.status === statusFilter); } // Filtro de prioridad if (priorityFilter !== "all") { result = result.filter((task) => task.priority === priorityFilter); } return result; }, [tasks, searchValue, statusFilter, priorityFilter]); // Estadísticas rápidas const stats = useMemo(() => ({ total: tasks.length, completed: tasks.filter(t => t.status === '2').length, inProgress: tasks.filter(t => t.status === '1').length, highPriority: tasks.filter(t => t.priority === '3').length, }), [tasks]); // Limpiar filtros const handleClearFilters = () => { setSearchValue(""); setStatusFilter("all"); setPriorityFilter("all"); }; const isFiltered = searchValue !== "" || statusFilter !== "all" || priorityFilter !== "all"; if (tasks.length === 0 && !isLoading) { return ( <> setIsCreateSheetOpen(true)} /> > ); } return ( {/* Stats rápidos */} Total: {stats.total} Completadas: {stats.completed} En progreso: {stats.inProgress} {stats.highPriority > 0 && ( Alta prioridad: {stats.highPriority} )} {/* Toolbar */} {/* Búsqueda */} setSearchValue(e.target.value)} className="pl-8 h-9" /> {/* Filtro estado */} Todos Borrador Validada Completada {/* Filtro prioridad */} Todas Alta Media Baja Sin prioridad {/* Limpiar */} {isFiltered && ( Limpiar )} {/* Toggle vista */} setViewMode("table")} > setViewMode("grid")} > {/* Nueva tarea */} setIsCreateSheetOpen(true)}> Nueva tarea {/* Contenido */} {viewMode === "table" ? ( ) : ( {filteredTasks.map((task) => ( ))} )} {/* Mensaje sin resultados */} {filteredTasks.length === 0 && tasks.length > 0 && ( No se encontraron tareas con los filtros aplicados. Limpiar filtros )} {/* Sheet de creación de tarea */} {/* Sheet de edición de tarea */} { setIsEditSheetOpen(open); if (!open) setTaskToEdit(null); }} mode="edit" projectId={projectId} task={taskToEdit} availableTasks={tasks} onSuccess={handleEditSuccess} /> {/* Diálogo de confirmación de eliminación */} { setIsDeleteDialogOpen(open); if (!open) setTaskToDelete(null); }} onConfirm={handleConfirmDelete} title="¿Eliminar tarea?" itemName={taskToDelete?.title} isDeleting={isDeleting} /> ); }
{task.title}
{task.ref}
Este proyecto aún no tiene tareas asignadas. Crea la primera tarea para comenzar.
No se encontraron tareas con los filtros aplicados.