import { useEffect } from 'react' import { useNavigate, Link } from '@tanstack/react-router' import { ChevronDown, Sun, Moon, LogOut, Settings, Menu } from 'lucide-react' import { useQuery } from '@tanstack/react-query' import { useCommandPalette } from '@/components/command-palette/useCommandPalette' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { useAuth, isSuperAdmin } from '@/lib/auth' import { useUIStore } from '@/lib/store' import { tenantsApi, metricsApi } from '@/lib/api' import { useEventStreamContext } from '@/contexts/EventStreamContext' import type { ConnectionState } from '@/hooks/useEventStream' import { NotificationBell } from '@/components/alerts/NotificationBell' const SYSTEM_TENANT_ID = '00000000-0000-0000-0000-000000000000' const CONNECTION_COLORS: Record = { connected: 'bg-success', connecting: 'bg-warning animate-pulse', reconnecting: 'bg-warning animate-pulse', disconnected: 'bg-error', } const CONNECTION_LABELS: Record = { connected: 'Connected', connecting: 'Connecting', reconnecting: 'Reconnecting', disconnected: 'Disconnected', } // Generate a deterministic color from a string function tenantColor(name: string): string { const colors = [ 'bg-info', 'bg-success', 'bg-accent', 'bg-warning', 'bg-error', 'bg-info', 'bg-accent', 'bg-success', ] let hash = 0 for (let i = 0; i < name.length; i++) { hash = name.charCodeAt(i) + ((hash << 5) - hash) } return colors[Math.abs(hash) % colors.length] } export function ContextStrip() { const { user, logout } = useAuth() const { selectedTenantId, setSelectedTenantId, theme, setTheme, setMobileSidebarOpen } = useUIStore() const { connectionState } = useEventStreamContext() const navigate = useNavigate() const superAdmin = isSuperAdmin(user) // Tenant list (super_admin only) const { data: tenants } = useQuery({ queryKey: ['tenants'], queryFn: tenantsApi.list, enabled: superAdmin, select: (data) => data.filter((t) => t.id !== SYSTEM_TENANT_ID), }) const selectedTenant = tenants?.find((t) => t.id === selectedTenantId) // Auto-select when there's exactly one tenant and nothing selected useEffect(() => { if (superAdmin && tenants && tenants.length === 1 && !selectedTenantId) { setSelectedTenantId(tenants[0].id) } }, [tenants, selectedTenantId, superAdmin, setSelectedTenantId]) // Fleet summary for status indicators const tenantId = superAdmin ? selectedTenantId : user?.tenant_id const { data: fleet } = useQuery({ queryKey: ['fleet-summary', superAdmin ? 'all' : tenantId], queryFn: () => superAdmin && !selectedTenantId ? metricsApi.fleetSummaryAll() : tenantId ? metricsApi.fleetSummary(tenantId) : Promise.resolve([]), enabled: !!tenantId || superAdmin, refetchInterval: 30_000, }) const offlineCount = fleet?.filter((d) => d.status === 'offline').length ?? 0 const degradedCount = fleet?.filter((d) => d.status === 'degraded').length ?? 0 const handleLogout = async () => { await logout() void navigate({ to: '/login' }) } // User initials for avatar const initials = user?.name ? user.name.split(' ').map((w) => w[0]).join('').slice(0, 2).toUpperCase() : user?.email?.slice(0, 2).toUpperCase() ?? '?' // Tenant display name for non-super_admin const tenantName = superAdmin ? (selectedTenant?.name ?? 'All Orgs') : user?.name ?? 'Tenant' return (
{/* Mobile hamburger */} {/* Left: Org switcher */}
{superAdmin && tenants && tenants.length > 0 ? (
{tenantName[0]?.toUpperCase()}
{tenantName}
Organization setSelectedTenantId(null)} className="text-xs"> All Orgs {tenants.map((tenant) => ( setSelectedTenantId(tenant.id)} className="text-xs" >
{tenant.name[0]?.toUpperCase()}
{tenant.name}
))}
) : ( {superAdmin ? 'No orgs' : (user?.name ?? 'Tenant')} )}
{/* Center: Status indicators */}
{fleet ? ( <> {offlineCount > 0 && ( )} {degradedCount > 0 && ( )} {offlineCount === 0 && degradedCount === 0 && fleet.length > 0 && ( All systems nominal )} {fleet.length === 0 && ( No devices )} ) : ( Status loading... )}
{/* Right: Actions */}
{/* Notification bell */} {tenantId && } {/* Command palette shortcut */} {/* Connection status dot */}
{/* Theme toggle */} {/* User avatar dropdown */}
{initials}
{user?.email}
Settings void handleLogout()} className="text-error text-xs"> Sign out
) }