"use client"; import { useState, useEffect, useMemo } from "react"; import { FolderKanban, RefreshCw, Plus } from "lucide-react"; import { toast } from "sonner"; import { Project } from "@/types/project"; import { getProjects, deleteProject } from "@/lib/projectsService"; import { DataTable } from "./data-table"; import { DataTableToolbar } from "./data-table-toolbar"; import { DataTableSkeleton } from "./data-table-skeleton"; import { EmptyState } from "./empty-state"; import { createProjectColumns } from "./columns"; import { ProjectFormSheet } from "@/components/project-form/project-form-sheet"; import { DeleteConfirmationDialog } from "@/components/ui/delete-confirmation-dialog"; import { Button } from "@/components/ui/button"; export function ProjectsTable() { const [projects, setProjects] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // Filtros const [searchValue, setSearchValue] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); // Estados para crear/editar/eliminar const [isCreateSheetOpen, setIsCreateSheetOpen] = useState(false); const [isEditSheetOpen, setIsEditSheetOpen] = useState(false); const [projectToEdit, setProjectToEdit] = useState(null); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [projectToDelete, setProjectToDelete] = useState(null); const [isDeleting, setIsDeleting] = useState(false); // Cargar proyectos const fetchProjects = async () => { setIsLoading(true); setError(null); try { const data = await getProjects(); setProjects(data); } catch (err) { console.error("Error fetching projects:", err); setError("Error al cargar los proyectos. Por favor, intenta de nuevo."); } finally { setIsLoading(false); } }; useEffect(() => { fetchProjects(); }, []); // Handlers para CRUD const handleProjectCreated = (newProject: Project) => { setProjects(prev => [newProject, ...prev]); }; const handleEditProject = (project: Project) => { setProjectToEdit(project); setIsEditSheetOpen(true); }; const handleEditSuccess = (updatedProject: Project) => { setProjects(prev => prev.map(p => p.id === updatedProject.id ? updatedProject : p)); setProjectToEdit(null); }; const handleDeleteProject = (project: Project) => { setProjectToDelete(project); setIsDeleteDialogOpen(true); }; const handleConfirmDelete = async () => { if (!projectToDelete) return; setIsDeleting(true); try { await deleteProject(projectToDelete.id); setProjects(prev => prev.filter(p => p.id !== projectToDelete.id)); setIsDeleteDialogOpen(false); setProjectToDelete(null); } catch (error) { console.error("Error deleting project:", error); toast.error("Error al eliminar el proyecto", { description: "No se pudo eliminar el proyecto. Inténtalo de nuevo.", }); } finally { setIsDeleting(false); } }; // Crear columnas con callbacks const columns = useMemo(() => createProjectColumns({ onEdit: handleEditProject, onDelete: handleDeleteProject, }), []); // Filtrar proyectos const filteredProjects = useMemo(() => { let result = [...projects]; // Filtro de búsqueda (nombre o referencia) if (searchValue) { const search = searchValue.toLowerCase(); result = result.filter( (project) => project.name.toLowerCase().includes(search) || project.ref.toLowerCase().includes(search) || project.client.toLowerCase().includes(search) ); } // Filtro de estado if (statusFilter !== "all") { result = result.filter((project) => project.status === statusFilter); } return result; }, [projects, searchValue, statusFilter]); // Limpiar filtros const handleClearFilters = () => { setSearchValue(""); setStatusFilter("all"); }; // Contar seleccionados (placeholder - el DataTable lo maneja internamente) const selectedCount = 0; // Estado de error if (error) { return (

Error al cargar

{error}

); } // Estado de carga if (isLoading) { return ; } // Estado vacío if (projects.length === 0) { return ( <> setIsCreateSheetOpen(true)} /> ); } return (
{/* Sheet de creación */} {/* Sheet de edición */} { setIsEditSheetOpen(open); if (!open) setProjectToEdit(null); }} mode="edit" project={projectToEdit} onSuccess={handleEditSuccess} /> {/* Diálogo de confirmación de eliminación */} { setIsDeleteDialogOpen(open); if (!open) setProjectToDelete(null); }} onConfirm={handleConfirmDelete} title="¿Eliminar proyecto?" itemName={projectToDelete?.name} description={`Esta acción eliminará el proyecto "${projectToDelete?.name}" y todas sus tareas asociadas. Esta acción no se puede deshacer.`} isDeleting={isDeleting} />
); }