154 lines
4.5 KiB
TypeScript
154 lines
4.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from 'react';
|
|
import ProjectCard from './project-card';
|
|
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>
|
|
);
|
|
}
|
|
|
|
// 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}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
// 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}
|
|
/>
|
|
</>
|
|
);
|
|
} |