import { useExperimental } from '@/hooks/useExperimental'; import { RefreshCw, Search, Camera, Network, SlidersHorizontal, Send, KeyRound, ArrowLeftRight, } from 'lucide-react'; import { FleetMasthead } from './fleet/FleetMasthead'; import { ReconnectingOverlay } from './FleetView/ReconnectingOverlay'; import { NodeUpdatesSheet } from './FleetView/NodeUpdatesSheet'; import { LocalUpdateConfirmDialog } from './FleetView/LocalUpdateConfirmDialog'; import { OverviewTab } from './FleetView/OverviewTab'; import { useFleetPreferences } from './FleetView/hooks/useFleetPreferences'; import { useFleetUpdateStatus } from './FleetView/hooks/useFleetUpdateStatus'; import { useFleetPolling } from './FleetView/hooks/useFleetPolling'; import { useFleetOverview } from './FleetView/hooks/useFleetOverview'; import { Button } from '@/components/ui/button'; import { Tabs, TabsContent, TabsList, TabsTrigger, TabsHighlight, TabsHighlightItem } from '@/components/ui/tabs'; import { springs } from '@/lib/motion'; import { useLicense } from '@/context/LicenseContext'; import { AdmiralGate } from './AdmiralGate'; import FleetSnapshots from './FleetSnapshots'; import { FleetConfiguration } from './fleet/FleetConfiguration'; import { FleetSoonPlaceholder } from './fleet/FleetSoonPlaceholder'; import { RoutingTab } from './fleet/RoutingTab'; import { DeploymentsTab } from './blueprints/DeploymentsTab'; interface FleetViewProps { onNavigateToNode: (nodeId: number, stackName: string) => void; } export function FleetView({ onNavigateToNode }: FleetViewProps) { const { isPaid, license } = useLicense(); const isAdmiral = isPaid && license?.variant === 'admiral'; const experimental = useExperimental(); const { prefs, updatePrefs } = useFleetPreferences(); const updateStatus = useFleetUpdateStatus(); const overview = useFleetOverview({ isPaid, prefs, updatePrefs, updateStatuses: updateStatus.updateStatuses }); useFleetPolling({ fetchOverview: overview.fetchOverview, fetchUpdateStatus: updateStatus.fetchUpdateStatus, updateStatuses: updateStatus.updateStatuses, }); const { mastheadStats, lastSyncAt, loading, refreshing } = overview; return (
Overview Snapshots {isAdmiral && ( Traffic ยท Routing )} Status {isPaid && ( Deployments )} {experimental && ( <> Federation Secrets )}
{isAdmiral && ( )} {isPaid && ( )} {experimental && ( <> } kicker="Federation" title="The fleet as one logical surface" description="Pin policies, drain a node for maintenance, weight-aware scheduling. This stack runs on whichever node has capacity." plannedActions={['Pin policy', 'Drain node', 'Cordon', 'Capacity plan']} /> } kicker="Secrets" title="One source of truth for env, creds and certs" description="Push to selected nodes, rotate centrally, audit who-saw-what. Solves silent drift across copies." plannedActions={['Sync env', 'Rotate', 'Audit', 'Pin to nodes']} /> )}
{updateStatus.reconnecting && ( )} { if (!open) updateStatus.setLocalUpdateConfirm(null); }} onConfirm={updateStatus.confirmLocalUpdate} />
); }