Files
sistema_base/apps/web/feactures/training/components/training-tables/cell-action.tsx

150 lines
4.5 KiB
TypeScript

'use client';
import { AlertModal } from '@/components/modal/alert-modal';
import { useDeleteTraining } from '@/feactures/training/hooks/use-training';
import { TrainingSchema } from '@/feactures/training/schemas/training';
import { Button } from '@repo/shadcn/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@repo/shadcn/tooltip';
import { Edit, Eye, Trash } from 'lucide-react';
import { useSession } from 'next-auth/react';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { TrainingViewModal } from '../training-view-modal';
interface CellActionProps {
data: TrainingSchema;
apiUrl: string;
}
export const CellAction: React.FC<CellActionProps> = ({ data, apiUrl }) => {
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
const [viewOpen, setViewOpen] = useState(false);
const { mutate: deleteTraining } = useDeleteTraining();
const router = useRouter();
const { data: session } = useSession();
const onConfirm = async () => {
try {
setLoading(true);
deleteTraining(data.id!);
setOpen(false);
} catch (error) {
console.error('Error:', error);
} finally {
setLoading(false);
}
};
// Mapear roles a minúsculas para comparación segura
const userRoles = session?.user?.role?.map((r) => r.rol.toLowerCase()) || [];
const isAdminOrSuper = userRoles.some((r) =>
['superadmin', 'admin'].includes(r),
);
// Soporta tanto 'coordinator' como 'coordinador'
const isCoordinator = userRoles.some(r =>
r.includes('coordinator') || r.includes('coordinador')
);
const isOtherAuthorized = userRoles.some((r) =>
['autoridad', 'manager'].includes(r),
);
// El creador del registro: intentamos createdBy o created_by por si acaso
const createdBy = data.createdBy ?? (data as any).created_by;
// Comparación robusta de IDs
const isOwner = createdBy !== undefined &&
createdBy !== null &&
Number(createdBy) === Number(session?.user?.id);
return (
<>
<AlertModal
isOpen={open}
onClose={() => setOpen(false)}
onConfirm={onConfirm}
loading={loading}
title="¿Estás seguro que desea eliminar este registro?"
description="Esta acción no se puede deshacer."
/>
<TrainingViewModal
isOpen={viewOpen}
onClose={() => setViewOpen(false)}
data={data}
/>
<div className="flex gap-1">
{/* VER DETALLE: superadmin, admin, autoridad, manager, or owner coordinator */}
{(isAdminOrSuper || isOtherAuthorized || (isCoordinator && isOwner)) && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
onClick={() => setViewOpen(true)}
>
<Eye className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Ver detalle</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
{/* EDITAR: Superadmin, admin OR (coordinator if owner) */}
{(isAdminOrSuper || (isCoordinator && isOwner)) && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
onClick={() =>
router.push(`/dashboard/formulario/editar/${data.id}`)
}
>
<Edit className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Editar</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
{/* ELIMINAR: Solo superadmin y admin */}
{isAdminOrSuper && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
onClick={() => setOpen(true)}
>
<Trash className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Eliminar</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
</div>
</>
);
};