import { useState } from 'react'; import { extractApiError } from '@/api/client'; import { useC2Callbacks, useExecuteC2 } from '@/hooks/useC2'; import type { C2Callback } from '@/api/types'; import { useToast } from '@/hooks/useToast'; interface ExecuteViaC2ModalProps { simulationId: number; engagementId: number; initialCommands: string; onClose: () => void; } function formatCheckin(ts: string): string { // Show ISO timestamp as-is — it's a data cell (font-mono) return ts; } export function ExecuteViaC2Modal({ simulationId, engagementId, initialCommands, onClose, }: ExecuteViaC2ModalProps): JSX.Element { const { push } = useToast(); const callbacksQuery = useC2Callbacks(engagementId, { enabled: true }); const executeMutation = useExecuteC2(simulationId, engagementId); const [selectedId, setSelectedId] = useState(null); const [commands, setCommands] = useState(initialCommands); const [submitError, setSubmitError] = useState(null); const callbacks: C2Callback[] = callbacksQuery.data?.callbacks ?? []; const commandLines = commands .split('\n') .map((l) => l.trim()) .filter(Boolean); const canLaunch = selectedId !== null && commandLines.length > 0; const onLaunch = async () => { if (!canLaunch) return; setSubmitError(null); try { const result = await executeMutation.mutateAsync({ callback_display_id: selectedId, commands: commandLines, }); push(`${result.tasks.length} task(s) submitted`, 'success'); onClose(); } catch (err) { setSubmitError(extractApiError(err, 'Could not execute via C2')); } }; return (