+ {/* Scan identification */}
+
+
+
+
Baseline
+
{data.scanA.image_ref}
+
{new Date(data.scanA.scanned_at).toLocaleString()}
+
+
+
+
Current
+
{data.scanB.image_ref}
+
{new Date(data.scanB.scanned_at).toLocaleString()}
+
+
+
+ {crossImage && (
+
+
+
+ You are comparing scans from two different image references. Package-level changes may reflect image differences rather than CVE drift.
+
+
+ )}
+
+ {/* Delta ribbon */}
+ {addedCounts && removedCounts && (
+
+ {(['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] as VulnSeverity[]).map((sev) => {
+ const delta = formatDelta(addedCounts[sev], removedCounts[sev]);
+ const toneClass =
+ delta.tone === 'warning'
+ ? 'text-warning border-warning/40 bg-warning/10'
+ : delta.tone === 'success'
+ ? 'text-success border-success/40 bg-success/10'
+ : 'text-muted-foreground border-border bg-muted/30';
+ return (
+
+ {sev}
+ {delta.text}
+
+ );
+ })}
+
+ )}
+
+
+ {/* Filter pills */}
+
+
{ setFilter('added'); setPage(0); }}
+ >
+
+ Added ({data.added.length})
+
+
{ setFilter('removed'); setPage(0); }}
+ >
+
+ Removed ({data.removed.length})
+
+
{ setFilter('unchanged'); setPage(0); }}
+ >
+
+ Unchanged ({data.unchanged.length})
+
+ {needsPagination && (
+
+ setPage(Math.max(0, safePage - 1))}
+ disabled={safePage === 0}
+ >
+
+
+
+ {safePage + 1} / {totalPages}
+
+ setPage(Math.min(totalPages - 1, safePage + 1))}
+ disabled={safePage >= totalPages - 1}
+ >
+
+
+
+ )}
+
+
+
+
+ {pageItems.length === 0 ? (
+
+
+
+ {filter === 'added' && 'No new findings. Nothing regressed between these scans.'}
+ {filter === 'removed' && 'No findings were resolved between these scans.'}
+ {filter === 'unchanged' && 'No findings are shared between the two scans.'}
+
+
+ ) : (
+
+
+
+ CVE
+ Package
+ Severity
+ Status
+
+
+
+ {pageItems.map((v, idx) => {
+ const rowClass =
+ filter === 'added'
+ ? 'bg-destructive/5'
+ : filter === 'removed'
+ ? 'bg-success/5'
+ : 'opacity-70';
+ return (
+
+
+ {v.primary_url ? (
+
+ {v.vulnerability_id}
+
+ ) : (
+ v.vulnerability_id
+ )}
+
+
+ {v.pkg_name}
+
+
+
+
+
+ {filter === 'added' && (
+
+
+ Added
+
+ )}
+ {filter === 'removed' && (
+
+
+ Removed
+
+ )}
+ {filter === 'unchanged' && (
+
+
+ Unchanged
+
+ )}
+
+
+ );
+ })}
+
+
+ )}
+
+
+
+ )}
+