diff --git a/decnet_web/src/components/AttackerDetail.tsx b/decnet_web/src/components/AttackerDetail.tsx
index 15a9ff2b..f0d9262c 100644
--- a/decnet_web/src/components/AttackerDetail.tsx
+++ b/decnet_web/src/components/AttackerDetail.tsx
@@ -1,9 +1,10 @@
import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
-import { Activity, ArrowLeft, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Crosshair, Fingerprint, Shield, Clock, Wifi, Lock, FileKey, Radio, Timer, Paperclip } from 'lucide-react';
+import { Activity, ArrowLeft, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Crosshair, Fingerprint, Shield, Clock, Wifi, Lock, FileKey, Radio, Timer, Paperclip, Terminal, Package, FileText } from 'lucide-react';
import api from '../utils/api';
import ArtifactDrawer from './ArtifactDrawer';
import SessionDrawer from './SessionDrawer';
+import EmptyState from './EmptyState/EmptyState';
import './Dashboard.css';
interface AttackerBehavior {
@@ -964,9 +965,12 @@ const AttackerDetail: React.FC = () => {
) : (
-
- NO BEHAVIORAL DATA YET — PROFILER HAS NOT RUN FOR THIS ATTACKER
-
+
)}
@@ -1028,9 +1032,11 @@ const AttackerDetail: React.FC = () => {
) : (
-
- {serviceFilter ? `NO ${serviceFilter.toUpperCase()} COMMANDS CAPTURED` : 'NO COMMANDS CAPTURED'}
-
+
)}
);
@@ -1177,9 +1183,11 @@ const AttackerDetail: React.FC = () => {
) : (
-
- NO ARTIFACTS CAPTURED FROM THIS ATTACKER
-
+
)}
@@ -1258,9 +1266,11 @@ const AttackerDetail: React.FC = () => {
) : (
-
- NO SESSION TRANSCRIPTS RECORDED FROM THIS ATTACKER
-
+
)}
diff --git a/decnet_web/src/components/Attackers.tsx b/decnet_web/src/components/Attackers.tsx
index 81c67190..852547fc 100644
--- a/decnet_web/src/components/Attackers.tsx
+++ b/decnet_web/src/components/Attackers.tsx
@@ -1,7 +1,8 @@
import React, { useEffect, useState } from 'react';
import { useSearchParams, useNavigate } from 'react-router-dom';
-import { Search, ChevronLeft, ChevronRight, UserX } from 'lucide-react';
+import { Search, ChevronLeft, ChevronRight, Users } from 'lucide-react';
import api from '../utils/api';
+import EmptyState from './EmptyState/EmptyState';
import './Dashboard.css';
import './Attackers.css';
@@ -163,14 +164,13 @@ const Attackers: React.FC = () => {
{loading ? (
-
- SCANNING THREAT PROFILES...
-
+
) : attackers.length === 0 ? (
-
-
- NO ACTIVE THREATS PROFILED YET
-
+
) : (
{attackers.map(a => {
diff --git a/decnet_web/src/components/Bounty.tsx b/decnet_web/src/components/Bounty.tsx
index f3aecfdd..a2e7b7d4 100644
--- a/decnet_web/src/components/Bounty.tsx
+++ b/decnet_web/src/components/Bounty.tsx
@@ -2,10 +2,11 @@ import React, { useEffect, useState } from 'react';
import { useSearchParams, useNavigate } from 'react-router-dom';
import {
Archive, Search, ChevronLeft, ChevronRight, Filter, Key, Package, ChevronRight as ChevR,
- ArchiveX,
+ Target,
} from 'lucide-react';
import api from '../utils/api';
import BountyInspector from './BountyInspector';
+import EmptyState from './EmptyState/EmptyState';
import './Dashboard.css';
import './Bounty.css';
@@ -220,12 +221,11 @@ const Bounty: React.FC = () => {
}) : (
-
-
-
- {loading ? 'RETRIEVING ARTIFACTS...' : 'THE VAULT IS EMPTY'}
-
-
+
|
)}
diff --git a/decnet_web/src/components/CommandPalette/CommandPalette.tsx b/decnet_web/src/components/CommandPalette/CommandPalette.tsx
index ebbf42d8..45c2b9b4 100644
--- a/decnet_web/src/components/CommandPalette/CommandPalette.tsx
+++ b/decnet_web/src/components/CommandPalette/CommandPalette.tsx
@@ -2,7 +2,9 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
import {
LayoutDashboard, Server, Network, Terminal, Archive, Crosshair,
PlusCircle, Pause, RefreshCw, Download, HardDrive, Package, UserPlus, Settings,
+ SearchX,
} from 'lucide-react';
+import EmptyState from '../EmptyState/EmptyState';
import './CommandPalette.css';
type IconComponent = React.ComponentType<{ size?: number; className?: string }>;
@@ -141,7 +143,7 @@ const CommandPalette: React.FC
= ({ open, onClose, onNav, onAction }) =>
))}
{filtered.length === 0 && (
- NO COMMAND MATCHES
+
)}
diff --git a/decnet_web/src/components/Dashboard.tsx b/decnet_web/src/components/Dashboard.tsx
index 39a08e1c..20210be6 100644
--- a/decnet_web/src/components/Dashboard.tsx
+++ b/decnet_web/src/components/Dashboard.tsx
@@ -1,9 +1,10 @@
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import './Dashboard.css';
-import { Shield, Users, Activity, Clock, Paperclip, Crosshair, Flame, Archive } from 'lucide-react';
+import { Shield, Users, Activity, Clock, Paperclip, Crosshair, Flame, Archive, ShieldOff, Server } from 'lucide-react';
import { parseEventBody } from '../utils/parseEventBody';
import ArtifactDrawer from './ArtifactDrawer';
+import EmptyState from './EmptyState/EmptyState';
interface Stats {
total_logs: number;
@@ -417,7 +418,13 @@ const Dashboard: React.FC = ({ searchQuery }) => {
);
}) : (
- | NO INTERACTION DETECTED |
+
+
+ |
)}
@@ -454,7 +461,7 @@ const Dashboard: React.FC = ({ searchQuery }) => {
))}
) : (
- NO ACTIVITY
+
)}
@@ -486,7 +493,7 @@ const Dashboard: React.FC = ({ searchQuery }) => {
))}
) : (
- NO ATTACKERS YET
+
)}
diff --git a/decnet_web/src/components/LiveLogs.tsx b/decnet_web/src/components/LiveLogs.tsx
index 1c56be1a..275d4216 100644
--- a/decnet_web/src/components/LiveLogs.tsx
+++ b/decnet_web/src/components/LiveLogs.tsx
@@ -2,11 +2,12 @@ import React, { useEffect, useState, useRef, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import {
Terminal, Search, BarChart3, ChevronLeft, ChevronRight,
- Play, Pause, Paperclip, Download, SearchX, X as XIcon,
+ Play, Pause, Paperclip, Download, Radio, X as XIcon,
} from 'lucide-react';
import api from '../utils/api';
import { parseEventBody } from '../utils/parseEventBody';
import ArtifactDrawer from './ArtifactDrawer';
+import EmptyState from './EmptyState/EmptyState';
import './Dashboard.css';
import './LiveLogs.css';
@@ -357,12 +358,11 @@ const LiveLogs: React.FC = () => {
}) : (
|
-
-
-
- {loading ? 'RETRIEVING DATA...' : 'NO LOGS MATCHING CRITERIA'}
-
-
+
|
)}
diff --git a/decnet_web/src/components/RemoteUpdates.tsx b/decnet_web/src/components/RemoteUpdates.tsx
index 7f692f9f..f294388f 100644
--- a/decnet_web/src/components/RemoteUpdates.tsx
+++ b/decnet_web/src/components/RemoteUpdates.tsx
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
import api from '../utils/api';
+import EmptyState from './EmptyState/EmptyState';
import './Dashboard.css';
import {
Upload, RefreshCw, RotateCcw, Package, AlertTriangle, CheckCircle,
@@ -222,11 +223,11 @@ const RemoteUpdates: React.FC = () => {
)}
{hosts.length === 0 ? (
-
-
- No workers with an updater bundle are enrolled. Run{' '}
- decnet swarm enroll --host <name> --updater to add one.
-
+
) : (
{hosts.map((h) => {
diff --git a/decnet_web/src/components/SwarmHosts.tsx b/decnet_web/src/components/SwarmHosts.tsx
index d9fb1aad..d9f0634a 100644
--- a/decnet_web/src/components/SwarmHosts.tsx
+++ b/decnet_web/src/components/SwarmHosts.tsx
@@ -1,8 +1,10 @@
import React, { useEffect, useState } from 'react';
+import { useNavigate } from 'react-router-dom';
import api from '../utils/api';
+import EmptyState from './EmptyState/EmptyState';
import './Dashboard.css';
import './Swarm.css';
-import { HardDrive, PowerOff, RefreshCw, Trash2, Wifi, WifiOff } from 'lucide-react';
+import { HardDrive, PowerOff, RefreshCw, Server, Trash2, Wifi, WifiOff } from 'lucide-react';
interface SwarmHost {
uuid: string;
@@ -20,6 +22,7 @@ interface SwarmHost {
const shortFp = (fp: string): string => (fp ? fp.slice(0, 16) + '…' : '—');
const SwarmHosts: React.FC = () => {
+ const navigate = useNavigate();
const [hosts, setHosts] = useState
([]);
const [loading, setLoading] = useState(true);
const [decommissioning, setDecommissioning] = useState>(new Set());
@@ -102,7 +105,12 @@ const SwarmHosts: React.FC = () => {
{loading ? (
Loading hosts…
) : hosts.length === 0 ? (
- No swarm hosts enrolled yet. Head to SWARM → Agent Enrollment to onboard one.
+ navigate('/swarm/enroll') }}
+ />
) : (
diff --git a/decnet_web/src/components/TopologyList/TopologyList.tsx b/decnet_web/src/components/TopologyList/TopologyList.tsx
index ba9c8d59..7bd85a4c 100644
--- a/decnet_web/src/components/TopologyList/TopologyList.tsx
+++ b/decnet_web/src/components/TopologyList/TopologyList.tsx
@@ -4,6 +4,7 @@ import { Network, Plus, Power, Trash2, UploadCloud, RefreshCw, Skull } from 'luc
import api from '../../utils/api';
import { clearLayout } from '../MazeNET/useMazeLayoutStore';
import CreateTopologyWizard from './CreateTopologyWizard';
+import EmptyState from '../EmptyState/EmptyState';
import './TopologyList.css';
interface TopologySummary {
@@ -237,9 +238,12 @@ const TopologyList: React.FC = () => {
))}
{!loading && rows.length === 0 && (
-
- No topologies yet. Click NEW TOPOLOGY to create one.
-
+ setCreating(true) }}
+ />
)}