diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx
index 34ad59c..76d61c1 100644
--- a/frontend/src/components/Layout.tsx
+++ b/frontend/src/components/Layout.tsx
@@ -1,6 +1,8 @@
import { useState } from 'react'
import { NavLink } from 'react-router-dom'
-import { Command, Activity, FolderKanban, Monitor, Settings, Menu, X } from 'lucide-react'
+import { Command, Activity, FolderKanban, Monitor, Settings, Menu, X, Wifi, WifiOff, Loader } from 'lucide-react'
+import { useSSEContext } from '../contexts/SSEContext'
+import type { SSEStatus } from '../hooks/useSSE'
const navItems = [
{ to: '/', icon: Command, label: 'Hub' },
@@ -10,9 +12,29 @@ const navItems = [
{ to: '/settings', icon: Settings, label: 'Settings' },
]
+/** Small status pill shown in the sidebar footer and mobile header. */
+function SSEStatusBadge({ status, showLabel = false }: { status: SSEStatus; showLabel?: boolean }) {
+ const cfg = {
+ connected: { icon: Wifi, color: 'text-green-500', label: 'Live' },
+ connecting: { icon: Loader, color: 'text-yellow-500 animate-spin', label: 'Connecting' },
+ reconnecting: { icon: Loader, color: 'text-yellow-500 animate-spin', label: 'Reconnecting' },
+ error: { icon: WifiOff, color: 'text-red-500', label: 'Disconnected' },
+ }[status]
+
+ const Icon = cfg.icon
+
+ return (
+
+
+ {showLabel && {cfg.label}}
+
+ )
+}
+
export default function Layout({ children }: { children: React.ReactNode }) {
const [expanded, setExpanded] = useState(false)
const [mobileOpen, setMobileOpen] = useState(false)
+ const { sseStatus } = useSSEContext()
return (
@@ -46,6 +68,15 @@ export default function Layout({ children }: { children: React.ReactNode }) {
))}
+ {/* SSE connection status — footer of sidebar */}
+
+
+ {expanded && (
+
+ {sseStatus === 'connected' ? 'Live updates on' : sseStatus}
+
+ )}
+
{/* Mobile Header + Bottom Nav */}
@@ -54,6 +85,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
Control Center
+