VcfImportScreen.swift
99 lignes · 3623 octets
import SwiftUI import UniformTypeIdentifiers // Port of ui/importvcf/VcfImportScreen.kt — .vcf file picker, progress, // import summary (imported / skipped duplicates / errors). struct VcfImportScreen: View { @StateObject private var viewModel = VcfImportViewModel() let onBack: () -> Void @State private var showPicker = false var body: some View { VStack(spacing: 0) { ScreenTopBar(title: "Import VCF", onBack: onBack) content } .background(C2VColor.fond) .toolbar(.hidden, for: .navigationBar) .fileImporter( isPresented: $showPicker, allowedContentTypes: [.vCard, .plainText, .data] ) { result in if case .success(let url) = result { viewModel.importFrom(url: url) } } } @ViewBuilder private var content: some View { switch viewModel.state { case .idle: VStack(spacing: 14) { Spacer() Text("Choisissez un fichier vCard (.vcf). Les doublons (e-mail ou téléphone) sont ignorés.") .font(C2VFont.bodyMedium) .foregroundColor(C2VColor.texteFaible) .multilineTextAlignment(.center) Button("Choisir un fichier") { showPicker = true } .buttonStyle(C2VPrimaryButtonStyle()) Spacer() } .padding(18) case .loading: VStack(spacing: 16) { Spacer() ProgressView().tint(C2VColor.ink) Text("Import en cours…") .font(C2VFont.bodyMedium) .foregroundColor(C2VColor.texteFaible) Spacer() } .frame(maxWidth: .infinity) case .done(let result): VStack(spacing: 12) { Spacer() Text("Résumé") .font(C2VFont.titleLarge) .foregroundColor(C2VColor.encre) Text(String(format: "Importés : %d", result.imported)) .font(C2VFont.bodyLarge) .foregroundColor(C2VColor.encre) Text(String(format: "Doublons ignorés : %d", result.skippedDuplicates)) .font(C2VFont.bodyMedium) .foregroundColor(C2VColor.texteFaible) Text(String(format: "Erreurs : %d", result.errors)) .font(C2VFont.bodyMedium) .foregroundColor(C2VColor.texteFaible) Button("Retour au carnet", action: onBack) .buttonStyle(C2VPrimaryButtonStyle()) Button("Importer un autre fichier") { viewModel.reset() showPicker = true } .buttonStyle(C2VOutlineButtonStyle()) Spacer() } .padding(18) case .error(let message): VStack(spacing: 12) { Spacer() Text(message) .font(C2VFont.bodyLarge) .foregroundColor(C2VColor.encre) .multilineTextAlignment(.center) Button("Réessayer") { viewModel.reset() showPicker = true } .buttonStyle(C2VPrimaryButtonStyle()) Button("Retour", action: onBack) .buttonStyle(C2VOutlineButtonStyle()) Spacer() } .padding(18) } } }
GitRust