// Auteur : Simon-Pierre Boucher — contact@spboucher.ai // MainWindow.swift — la fenêtre principale : sidebar (Accueil, Recherche, // Carte, les 12 univers avec accent + compteur live, Favoris, Historique, // Recherches & alertes, KA Agent, Statut) → volet de contenu premium. import SwiftUI struct MainWindowView: View { @EnvironmentObject private var pulse: EcosystemPulse @EnvironmentObject private var state: AppState @EnvironmentObject private var favorites: FavoritesStore @EnvironmentObject private var recents: RecentsStore @Environment(\.openWindow) private var openWindow @Environment(\.colorScheme) private var scheme var body: some View { NavigationSplitView { sidebar } detail: { detail .background(KATheme.paper(scheme)) } .frame(minWidth: 1000, minHeight: 640) .onAppear { state.openMain = { focusMainWindow(openWindow) } } } private var sidebar: some View { List(selection: $state.selection) { Section { Label("Accueil", systemImage: "house") .tag(SidebarSelection.home) Label("Recherche", systemImage: "magnifyingglass") .tag(SidebarSelection.search) Label("Carte", systemImage: "map") .tag(SidebarSelection.map) Label("KA Agent", systemImage: "sparkle") .tag(SidebarSelection.agent) } header: { GroupeKAMark(size: 15).padding(.vertical, 4) } Section("Univers") { ForEach(Ecosystem.all) { u in HStack(spacing: 8) { KALogo(id: u.id, size: 18, fallbackSymbol: u.symbol, fallbackAccent: u.accent) KAWordmark(universe: u, size: 12) Spacer(minLength: 4) if let n = pulse.totals[u.id] { Text(Double(n).compact) .font(.system(.caption2, design: .monospaced).weight(.bold)) .foregroundStyle(u.accent) .contentTransition(.numericText()) } } .tag(SidebarSelection.universe(u.id)) } HStack(spacing: 8) { KALogo(id: "groupe-ka", size: 18) Text("groupe-ka.com") .font(.system(size: 12, weight: .bold, design: .rounded)) } .tag(SidebarSelection.hub) .help("Le hub Groupe KA — le site, intégré dans l'app") } Section("Bibliothèque") { HStack { Label("Favoris", systemImage: "heart") Spacer() if favorites.count > 0 { Text("\(favorites.count)") .font(.system(.caption2, design: .monospaced).weight(.bold)) .foregroundStyle(.secondary) } } .tag(SidebarSelection.favorites) Label("Historique", systemImage: "clock.arrow.circlepath") .tag(SidebarSelection.history) HStack { Label("Recherches & alertes", systemImage: "bell") Spacer() if recents.alertCount > 0 { Text("+\(recents.alertCount)") .font(.system(.caption2, design: .monospaced).weight(.bold)) .padding(.horizontal, 6).padding(.vertical, 2) .background(Color.red.opacity(0.85), in: Capsule()) .foregroundStyle(.white) } } .tag(SidebarSelection.alerts) } Section { HStack { Label("Statut", systemImage: "waveform.path.ecg") Spacer() Text("\(pulse.servicesUp)/\(pulse.health.count)") .font(.system(.caption2, design: .monospaced).weight(.bold)) .foregroundStyle(pulse.servicesUp == pulse.health.count ? KATheme.green : .orange) } .tag(SidebarSelection.status) } } .listStyle(.sidebar) .navigationSplitViewColumnWidth(min: 215, ideal: 235) } @ViewBuilder private var detail: some View { switch state.selection ?? .home { case .home: HomeView() case .search: UniversalSearchView() case .map: MapExplorerView() case .agent: AgentChatView() case .status: StatusView() case .favorites: FavoritesView() case .history: HistoryView() case .alerts: AlertsView() case .hub: SiteView(url: Ecosystem.hubURL, title: "Groupe KA", accent: KATheme.green, logoID: "groupe-ka") case .universe(let id): if let u = Ecosystem.universe(id) { UniverseExplorerView(universe: u) .id(u.id) // réinitialise l'état quand on change d'univers } } } }