// // ReportGeneratingView.swift // Reflect // // Overlay shown during AI report generation with progress and cancel. // import SwiftUI struct ReportGeneratingView: View { let progress: Double let message: String let onCancel: () -> Void @Environment(\.colorScheme) private var colorScheme @State private var isPulsing = false var body: some View { ZStack { // Semi-transparent background Color.black.opacity(0.4) .ignoresSafeArea() VStack(spacing: 24) { // Sparkles icon Image(systemName: "sparkles") .font(.system(size: 44)) .foregroundStyle( LinearGradient( colors: [.purple, .blue], startPoint: .topLeading, endPoint: .bottomTrailing ) ) .scaleEffect(isPulsing ? 1.1 : 1.0) .opacity(isPulsing ? 0.8 : 1.0) .animation( UIAccessibility.isReduceMotionEnabled ? nil : .easeInOut(duration: 1.2).repeatForever(autoreverses: true), value: isPulsing ) // Progress bar VStack(spacing: 8) { ProgressView(value: progress) .progressViewStyle(.linear) .tint( LinearGradient( colors: [.purple, .blue], startPoint: .leading, endPoint: .trailing ) ) .accessibilityIdentifier(AccessibilityID.Reports.progressView) Text(message) .font(.subheadline) .foregroundStyle(.secondary) .multilineTextAlignment(.center) } // Cancel button Button(role: .cancel) { onCancel() } label: { Text("Cancel") .font(.subheadline.weight(.medium)) .foregroundColor(.secondary) } .accessibilityIdentifier(AccessibilityID.Reports.cancelButton) } .padding(32) .background( RoundedRectangle(cornerRadius: 20) .fill(colorScheme == .dark ? Color(.systemGray6) : .white) .shadow(radius: 20) ) .padding(.horizontal, 40) } .onAppear { if !UIAccessibility.isReduceMotionEnabled { isPulsing = true } } } }