trello_fake/components/dashboard/project-grid.tsx

154 lines
4.5 KiB
TypeScript
Raw Normal View History

"use client";
import { useState } from 'react';
import ProjectCard from './project-card';
2026-01-28 10:44:49 +00:00
import ProjectListItem from './project-list-item';
import { ProjectFormSheet } from '@/components/project-form/project-form-sheet';
import { DeleteConfirmationDialog } from '@/components/ui/delete-confirmation-dialog';
import { deleteProject } from '@/lib/projectsService';
import { Project } from '@/types/project';
interface ProjectGridProps {
projects: Project[];
viewMode: 'grid' | 'list';
onProjectUpdated?: (project: Project) => void;
onProjectDeleted?: (projectId: number) => void;
}
export default function ProjectGrid({
projects,
viewMode,
onProjectUpdated,
onProjectDeleted
}: ProjectGridProps) {
const [isEditSheetOpen, setIsEditSheetOpen] = useState(false);
const [projectToEdit, setProjectToEdit] = useState<Project | null>(null);
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [projectToDelete, setProjectToDelete] = useState<Project | null>(null);
const [isDeleting, setIsDeleting] = useState(false);
const handleEditProject = (project: Project) => {
setProjectToEdit(project);
setIsEditSheetOpen(true);
};
const handleDeleteProject = (project: Project) => {
setProjectToDelete(project);
setIsDeleteDialogOpen(true);
};
const handleEditSuccess = (updatedProject: Project) => {
onProjectUpdated?.(updatedProject);
setProjectToEdit(null);
};
const handleConfirmDelete = async () => {
if (!projectToDelete) return;
setIsDeleting(true);
try {
await deleteProject(projectToDelete.id);
onProjectDeleted?.(projectToDelete.id);
setIsDeleteDialogOpen(false);
setProjectToDelete(null);
} catch (error) {
console.error("Error deleting project:", error);
} finally {
setIsDeleting(false);
}
};
if (projects.length === 0) {
return (
<div className="text-center py-12">
<p className="text-muted-foreground">No se encontraron proyectos</p>
</div>
);
}
2026-01-28 10:44:49 +00:00
// Vista de lista
if (viewMode === 'list') {
return (
<>
<div className="flex flex-col gap-3">
{projects.map((project) => (
<ProjectListItem
key={project.id}
project={project}
onEdit={handleEditProject}
onDelete={handleDeleteProject}
/>
))}
</div>
{/* Sheet de edición */}
<ProjectFormSheet
open={isEditSheetOpen}
onOpenChange={(open) => {
setIsEditSheetOpen(open);
if (!open) setProjectToEdit(null);
}}
mode="edit"
project={projectToEdit}
onSuccess={handleEditSuccess}
/>
{/* Diálogo de confirmación de eliminación */}
<DeleteConfirmationDialog
open={isDeleteDialogOpen}
onOpenChange={(open) => {
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}
/>
</>
2026-01-28 10:44:49 +00:00
);
}
// Vista de grid (por defecto)
return (
<>
<div className="grid gap-6 grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
{projects.map((project) => (
<ProjectCard
key={project.id}
project={project}
onEdit={handleEditProject}
onDelete={handleDeleteProject}
/>
))}
</div>
{/* Sheet de edición */}
<ProjectFormSheet
open={isEditSheetOpen}
onOpenChange={(open) => {
setIsEditSheetOpen(open);
if (!open) setProjectToEdit(null);
}}
mode="edit"
project={projectToEdit}
onSuccess={handleEditSuccess}
/>
{/* Diálogo de confirmación de eliminación */}
<DeleteConfirmationDialog
open={isDeleteDialogOpen}
onOpenChange={(open) => {
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}
/>
</>
);
}