1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// ProfileView.swift — profil : KA ID (compte unique de l'écosystème), univers3// favoris, apparence, contacts complets du Groupe KA, pages légales, à propos.4import SwiftUI56struct ProfileView: View {7 @AppStorage("ka.favUniverses") private var favUniversesRaw = ""8 @AppStorage("ka.appearance") private var appearance = "auto"9 @Environment(\.colorScheme) private var scheme10 @StateObject private var kaid = KAIDManager.shared1112 private var favIDs: Set<String> {13 Set(favUniversesRaw.split(separator: ",").map(String.init))14 }1516 var body: some View {17 NavigationStack {18 List {19 Section {20 if let p = kaid.profile {21 KAIDCard(profile: p)22 .listRowInsets(EdgeInsets())23 .listRowBackground(Color.clear)24 Link(destination: Ecosystem.hubURL.appendingPathComponent("/compte")) {25 Label("Gérer mon profil sur groupe-ka.com", systemImage: "person.text.rectangle")26 }27 Button(role: .destructive) { kaid.logout() } label: {28 Label("Se déconnecter", systemImage: "rectangle.portrait.and.arrow.right")29 }30 } else {31 HStack(spacing: 14) {32 ZStack {33 RoundedRectangle(cornerRadius: 14, style: .continuous)34 .fill(KATheme.inkLight)35 .frame(width: 56, height: 56)36 Text("KA").font(.system(size: 22, weight: .bold, design: .rounded))37 .foregroundStyle(KATheme.lime)38 .rotationEffect(.degrees(-4))39 }40 VStack(alignment: .leading, spacing: 3) {41 Text("Votre KA ID").font(.headline)42 Text("Un seul compte pour les 13 plateformes de l'écosystème.")43 .font(.caption).foregroundStyle(.secondary)44 }45 }46 Button {47 kaid.login()48 } label: {49 HStack {50 Label("Se connecter avec KA ID", systemImage: "person.crop.circle.badge.checkmark")51 Spacer()52 if kaid.busy { ProgressView() }53 }54 }55 .disabled(kaid.busy)56 Link(destination: Ecosystem.signupURL) {57 Label("Créer un compte sur groupe-ka.com", systemImage: "arrow.up.right.square")58 }59 if let e = kaid.lastError {60 Text(e).font(.caption).foregroundStyle(.red)61 }62 }63 }6465 Section {66 ForEach(Ecosystem.all) { u in67 Button {68 var ids = favIDs69 if ids.contains(u.id) { ids.remove(u.id) } else { ids.insert(u.id) }70 favUniversesRaw = ids.sorted().joined(separator: ",")71 Haptics.tap()72 } label: {73 HStack {74 Image(systemName: u.symbol).foregroundStyle(u.accent).frame(width: 26)75 Text(u.name).foregroundStyle(.primary)76 Spacer()77 if favIDs.contains(u.id) {78 Image(systemName: "star.fill").foregroundStyle(.yellow)79 }80 }81 }82 }83 } header: {84 Text("Mes univers favoris")85 } footer: {86 Text("Vos univers favoris remontent en tête de l'accueil.")87 }8889 Section("Apparence") {90 Picker("Thème", selection: $appearance) {91 Text("Automatique").tag("auto")92 Text("Clair").tag("clair")93 Text("Sombre").tag("sombre")94 }95 }9697 Section("Joindre le Groupe KA") {98 ForEach(Ecosystem.contacts, id: \.email) { c in99 Link(destination: URL(string: "mailto:\(c.email)")!) {100 VStack(alignment: .leading, spacing: 2) {101 Text(c.email).font(.subheadline.weight(.semibold))102 Text(c.role).font(.caption).foregroundStyle(.secondary)103 }104 }105 }106 Link(destination: Ecosystem.hubURL) {107 Label("groupe-ka.com — le portail", systemImage: "globe")108 }109 Link(destination: Ecosystem.statusURL) {110 Label("État des services en direct", systemImage: "waveform.path.ecg")111 }112 }113114 Section("Légal") {115 ForEach(Ecosystem.legal, id: \.path) { l in116 Link(destination: Ecosystem.hubURL.appendingPathComponent(l.path)) {117 Text(l.label)118 }119 }120 Text(Ecosystem.disclaimer)121 .font(.caption2).foregroundStyle(.secondary)122 }123124 Section("À propos") {125 LabeledContent("Version", value: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0.0")126 LabeledContent("Écosystème", value: "\(Ecosystem.all.count) univers")127 Text("KA — tout l'écosystème Groupe-KA dans votre poche. Fait au Québec. 💚")128 .font(.caption).foregroundStyle(.secondary)129 }130 }131 .navigationTitle("Profil")132 .scrollContentBackground(.hidden)133 .background(KATheme.paper(scheme))134 }135 }136}137