import { Link } from 'react-router-dom'; import { Plus } from 'lucide-react'; import { extractApiError } from '@/api/client'; import type { Engagement } from '@/api/types'; import { useDeleteEngagement, useEngagementsList } from '@/hooks/useEngagements'; import { useAuth } from '@/hooks/useAuth'; import { useToast } from '@/hooks/useToast'; import { LoadingState } from '@/components/LoadingState'; import { ErrorState } from '@/components/ErrorState'; import { EmptyState } from '@/components/EmptyState'; import { StatusBadge } from '@/components/StatusBadge'; function formatDate(value: string | null): string { if (!value) return '—'; return value; } export function EngagementsListPage(): JSX.Element { const { data, isLoading, isError, error, refetch } = useEngagementsList(); const { canEditEngagements } = useAuth(); const { push } = useToast(); const deleteMutation = useDeleteEngagement(); const onDelete = async (eng: Engagement) => { if (!window.confirm(`Delete engagement "${eng.name}"? This cannot be undone.`)) return; try { await deleteMutation.mutateAsync(eng.id); push('Engagement deleted', 'success'); } catch (err) { push(extractApiError(err, 'Could not delete engagement'), 'error'); } }; return (

Engagements

Red team missions and their lifecycle status.

{canEditEngagements ? ( New engagement ) : null}
{isLoading ? : null} {isError ? ( refetch()} /> ) : null} {!isLoading && !isError && data && data.length === 0 ? ( New engagement ) : undefined } /> ) : null} {!isLoading && !isError && data && data.length > 0 ? (
{data.map((eng) => ( ))}
Name Status Start End Created by Actions
{eng.name} {formatDate(eng.start_date)} {formatDate(eng.end_date)} {eng.created_by.username}
View {canEditEngagements ? ( <> Edit ) : null}
) : null}
); }