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) }} + /> )}