feat(web): Identities + Campaigns list pages + THREAT DATA nav group

Adds proper /identities and /campaigns list pages following the
Bounty/Attackers convention (page-header + page-title-group +
controls-row + logs-section + logs-table + EmptyState). Both pages
live-update via the existing identity / campaign SSE streams.

Sidebar: Attackers, Identities, Campaigns now group under a
THREAT DATA NavGroup, matching the SWARM grouping pattern.

CampaignDetail and IdentityDetail rewritten to use the house class
system (page-header / logs-section / chip / dim-chip) instead of
inline styles. The campaign chip on IdentityDetail navigates to
/campaigns/:uuid; both pages share a small fp-group helper for
fingerprint listings (added to Dashboard.css).
This commit is contained in:
2026-04-26 09:32:00 -04:00
parent 7fafdd66de
commit cc2deb73f7
7 changed files with 713 additions and 322 deletions

View File

@@ -19,7 +19,9 @@ const LiveLogs = lazy(() => import('./components/LiveLogs'));
const Webhooks = lazy(() => import('./components/Webhooks'));
const Attackers = lazy(() => import('./components/Attackers'));
const AttackerDetail = lazy(() => import('./components/AttackerDetail'));
const Identities = lazy(() => import('./components/Identities'));
const IdentityDetail = lazy(() => import('./components/IdentityDetail'));
const Campaigns = lazy(() => import('./components/Campaigns'));
const CampaignDetail = lazy(() => import('./components/CampaignDetail'));
const Config = lazy(() => import('./components/Config'));
const Bounty = lazy(() => import('./components/Bounty'));
@@ -115,7 +117,9 @@ const AuthedShell: React.FC<AuthedShellProps> = ({ onLogout, onSearch, searchQue
<Route path="/credentials" element={<Credentials />} />
<Route path="/attackers" element={<Attackers />} />
<Route path="/attackers/:id" element={<AttackerDetail />} />
<Route path="/identities" element={<Identities />} />
<Route path="/identities/:id" element={<IdentityDetail />} />
<Route path="/campaigns" element={<Campaigns />} />
<Route path="/campaigns/:id" element={<CampaignDetail />} />
<Route path="/config" element={<Config />} />
<Route path="/swarm-updates" element={<RemoteUpdates />} />