Files
Reflect/Shared/Views/InsightsView/ReportGeneratingView.swift
Trey t 19b4c8b05b Add AI mood report feature with PDF export for therapist sharing
Adds a Reports tab to the Insights view with date range selection, two report
types (Quick Summary / Detailed), Foundation Models AI generation with batched
concurrent processing, and clinical PDF export via WKWebView HTML rendering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 10:13:54 -05:00

87 lines
2.8 KiB
Swift

//
// 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
}
}
}
}