1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// MainWindow.swift — la fenêtre principale : sidebar (Accueil, Recherche,3// Carte, les 12 univers avec accent + compteur live, Favoris, Historique,4// Recherches & alertes, KA Agent, Statut) → volet de contenu premium.5import SwiftUI67struct MainWindowView: View {8 @EnvironmentObject private var pulse: EcosystemPulse9 @EnvironmentObject private var state: AppState10 @EnvironmentObject private var favorites: FavoritesStore11 @EnvironmentObject private var recents: RecentsStore12 @Environment(\.openWindow) private var openWindow13 @Environment(\.colorScheme) private var scheme1415 var body: some View {16 NavigationSplitView {17 sidebar18 } detail: {19 detail20 .background(KATheme.paper(scheme))21 }22 .frame(minWidth: 1000, minHeight: 640)23 .onAppear {24 state.openMain = { focusMainWindow(openWindow) }25 }26 }2728 private var sidebar: some View {29 List(selection: $state.selection) {30 Section {31 Label("Accueil", systemImage: "house")32 .tag(SidebarSelection.home)33 Label("Recherche", systemImage: "magnifyingglass")34 .tag(SidebarSelection.search)35 Label("Carte", systemImage: "map")36 .tag(SidebarSelection.map)37 Label("KA Agent", systemImage: "sparkle")38 .tag(SidebarSelection.agent)39 } header: {40 GroupeKAMark(size: 15).padding(.vertical, 4)41 }4243 Section("Univers") {44 ForEach(Ecosystem.all) { u in45 HStack(spacing: 8) {46 Image(systemName: u.symbol)47 .font(.caption.weight(.semibold))48 .foregroundStyle(u.accent)49 .frame(width: 18)50 KAWordmark(universe: u, size: 12)51 Spacer(minLength: 4)52 if let n = pulse.totals[u.id] {53 Text(Double(n).compact)54 .font(.system(.caption2, design: .monospaced).weight(.bold))55 .foregroundStyle(u.accent)56 .contentTransition(.numericText())57 }58 }59 .tag(SidebarSelection.universe(u.id))60 }61 }6263 Section("Bibliothèque") {64 HStack {65 Label("Favoris", systemImage: "heart")66 Spacer()67 if favorites.count > 0 {68 Text("\(favorites.count)")69 .font(.system(.caption2, design: .monospaced).weight(.bold))70 .foregroundStyle(.secondary)71 }72 }73 .tag(SidebarSelection.favorites)74 Label("Historique", systemImage: "clock.arrow.circlepath")75 .tag(SidebarSelection.history)76 HStack {77 Label("Recherches & alertes", systemImage: "bell")78 Spacer()79 if recents.alertCount > 0 {80 Text("+\(recents.alertCount)")81 .font(.system(.caption2, design: .monospaced).weight(.bold))82 .padding(.horizontal, 6).padding(.vertical, 2)83 .background(Color.red.opacity(0.85), in: Capsule())84 .foregroundStyle(.white)85 }86 }87 .tag(SidebarSelection.alerts)88 }8990 Section {91 HStack {92 Label("Statut", systemImage: "waveform.path.ecg")93 Spacer()94 Text("\(pulse.servicesUp)/\(pulse.health.count)")95 .font(.system(.caption2, design: .monospaced).weight(.bold))96 .foregroundStyle(pulse.servicesUp == pulse.health.count ? KATheme.green : .orange)97 }98 .tag(SidebarSelection.status)99 }100 }101 .listStyle(.sidebar)102 .navigationSplitViewColumnWidth(min: 215, ideal: 235)103 }104105 @ViewBuilder106 private var detail: some View {107 switch state.selection ?? .home {108 case .home: HomeView()109 case .search: UniversalSearchView()110 case .map: MapExplorerView()111 case .agent: AgentChatView()112 case .status: StatusView()113 case .favorites: FavoritesView()114 case .history: HistoryView()115 case .alerts: AlertsView()116 case .universe(let id):117 if let u = Ecosystem.universe(id) {118 UniverseExplorerView(universe: u)119 .id(u.id) // réinitialise l'état quand on change d'univers120 }121 }122 }123}124