Swift 98.3%
Shell 1.7%
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 KALogo(id: u.id, size: 18,47 fallbackSymbol: u.symbol, fallbackAccent: u.accent)48 KAWordmark(universe: u, size: 12)49 Spacer(minLength: 4)50 if let n = pulse.totals[u.id] {51 Text(Double(n).compact)52 .font(.system(.caption2, design: .monospaced).weight(.bold))53 .foregroundStyle(u.accent)54 .contentTransition(.numericText())55 }56 }57 .tag(SidebarSelection.universe(u.id))58 }59 HStack(spacing: 8) {60 KALogo(id: "groupe-ka", size: 18)61 Text("groupe-ka.com")62 .font(.system(size: 12, weight: .bold, design: .rounded))63 }64 .tag(SidebarSelection.hub)65 .help("Le hub Groupe KA — le site, intégré dans l'app")66 }6768 Section("Bibliothèque") {69 HStack {70 Label("Favoris", systemImage: "heart")71 Spacer()72 if favorites.count > 0 {73 Text("\(favorites.count)")74 .font(.system(.caption2, design: .monospaced).weight(.bold))75 .foregroundStyle(.secondary)76 }77 }78 .tag(SidebarSelection.favorites)79 Label("Historique", systemImage: "clock.arrow.circlepath")80 .tag(SidebarSelection.history)81 HStack {82 Label("Recherches & alertes", systemImage: "bell")83 Spacer()84 if recents.alertCount > 0 {85 Text("+\(recents.alertCount)")86 .font(.system(.caption2, design: .monospaced).weight(.bold))87 .padding(.horizontal, 6).padding(.vertical, 2)88 .background(Color.red.opacity(0.85), in: Capsule())89 .foregroundStyle(.white)90 }91 }92 .tag(SidebarSelection.alerts)93 }9495 Section {96 HStack {97 Label("Statut", systemImage: "waveform.path.ecg")98 Spacer()99 Text("\(pulse.servicesUp)/\(pulse.health.count)")100 .font(.system(.caption2, design: .monospaced).weight(.bold))101 .foregroundStyle(pulse.servicesUp == pulse.health.count ? KATheme.green : .orange)102 }103 .tag(SidebarSelection.status)104 }105 }106 .listStyle(.sidebar)107 .navigationSplitViewColumnWidth(min: 215, ideal: 235)108 }109110 @ViewBuilder111 private var detail: some View {112 switch state.selection ?? .home {113 case .home: HomeView()114 case .search: UniversalSearchView()115 case .map: MapExplorerView()116 case .agent: AgentChatView()117 case .status: StatusView()118 case .favorites: FavoritesView()119 case .history: HistoryView()120 case .alerts: AlertsView()121 case .hub:122 SiteView(url: Ecosystem.hubURL, title: "Groupe KA",123 accent: KATheme.green, logoID: "groupe-ka")124 case .universe(let id):125 if let u = Ecosystem.universe(id) {126 UniverseExplorerView(universe: u)127 .id(u.id) // réinitialise l'état quand on change d'univers128 }129 }130 }131}132