import { useParams, Link } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import { getJob, getJobVerification, getAuditEvents } from '../api/client'; import PageHeader from '../components/PageHeader'; import StatusBadge from '../components/StatusBadge'; import ErrorState from '../components/ErrorState'; import { formatDateTime, timeAgo } from '../api/utils'; function InfoRow({ label, value }: { label: string; value: React.ReactNode }) { return (
{label} {value}
); } function VerificationBadge({ status }: { status?: string }) { if (!status) return ; const styles: Record = { success: 'bg-emerald-100 text-emerald-700', failed: 'bg-red-100 text-red-700', pending: 'bg-yellow-100 text-yellow-700', skipped: 'bg-gray-100 text-gray-600', }; const labels: Record = { success: 'Verified', failed: 'Failed', pending: 'Pending', skipped: 'Skipped', }; return ( {labels[status] || status} ); } export default function JobDetailPage() { const { id } = useParams<{ id: string }>(); const { data: job, isLoading, error, refetch } = useQuery({ queryKey: ['job', id], queryFn: () => getJob(id!), enabled: !!id, refetchInterval: 10000, }); const { data: verification } = useQuery({ queryKey: ['job-verification', id], queryFn: () => getJobVerification(id!), enabled: !!id && job?.type === 'Deployment' && job?.status === 'Completed', retry: false, }); const { data: auditData } = useQuery({ queryKey: ['audit', { resource_id: id }], queryFn: () => getAuditEvents({ resource_id: id!, per_page: '10' }), enabled: !!id, }); if (error) { return ( <> refetch()} /> ); } if (isLoading || !job) { return ( <>
Loading job...
); } return ( <>
{/* Job details */}

Job Information

{job.id}} /> } /> {job.certificate_id} } /> {job.agent_id && ( {job.agent_id} } /> )} {job.target_id && ( {job.target_id} } /> )} {job.last_error && ( {job.last_error} } /> )}
{/* Timeline */}

Timeline

{job.started_at && } {job.completed_at && } {job.completed_at && job.started_at && ( )}
{/* Verification section — only for deployment jobs */} {job.type === 'Deployment' && (

Post-Deployment Verification

{job.verification_status ? (
} /> {job.verified_at && } {job.verification_fingerprint && ( {job.verification_fingerprint}} /> )} {job.verification_error && ( {job.verification_error}} /> )} {verification && verification.verified && ( {verification.expected_fingerprint}} /> )}
) : (
{job.status === 'Completed' ? 'No verification data recorded' : 'Verification runs after deployment completes'}
)}
)} {/* Audit trail */} {auditData && auditData.data.length > 0 && (

Related Audit Events

{auditData.data.map(event => (
{event.action} by {event.actor}
{formatDateTime(event.timestamp)}
))}
)}
); }