import SwiftUI /// A polished, branded card summarising the month — designed to be rendered to /// an image and shared (screenshot-worthy, marketing-facing). Pulls only from /// data the Dashboard already computes. struct MonthlySummaryShareView: View { let monthLabel: String let totalValue: String let changeAmount: String let changePercentage: String let isPositive: Bool let streak: Int let mood: MonthlyCheckInMood? let rating: Int? let appName: String var qrCodeImage: UIImage? = nil var body: some View { VStack(alignment: .leading, spacing: 0) { // Header HStack { Text(monthLabel) .font(.caption.weight(.semibold)) .foregroundStyle(.white.opacity(0.85)) .textCase(.uppercase) Spacer() if streak >= 2 { HStack(spacing: 4) { Image(systemName: "flame.fill") .font(.caption2) Text(String(format: String(localized: "share_summary_streak_badge"), streak)) .font(.caption2.weight(.bold)) } .foregroundStyle(.white) .padding(.horizontal, 10) .padding(.vertical, 5) .background(Color.white.opacity(0.18)) .clipShape(Capsule()) } } Text("Monthly Summary") .font(.title.weight(.bold)) .foregroundStyle(.white) .padding(.top, 6) // Hero value VStack(alignment: .leading, spacing: 6) { Text("Portfolio Value") .font(.subheadline.weight(.semibold)) .foregroundStyle(.white.opacity(0.85)) Text(totalValue) .font(.system(size: 40, weight: .bold, design: .rounded)) .foregroundStyle(.white) .minimumScaleFactor(0.6) .lineLimit(1) } .padding(.top, 22) // Change since last check-in HStack(spacing: 8) { Image(systemName: isPositive ? "arrow.up.right" : "arrow.down.right") .font(.subheadline.weight(.bold)) Text("\(changeAmount) (\(changePercentage))") .font(.headline.weight(.bold)) Spacer() Text("since last check-in") .font(.caption) .foregroundStyle(.white.opacity(0.75)) } .foregroundStyle(.white) .padding(.horizontal, 14) .padding(.vertical, 10) .background(Color.white.opacity(0.15)) .clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous)) .padding(.top, 18) // Mood / rating if mood != nil || rating != nil { HStack(spacing: 14) { if let mood { HStack(spacing: 6) { Image(systemName: mood.iconName) .font(.subheadline) Text(mood.title) .font(.subheadline.weight(.semibold)) } .foregroundStyle(.white) } if let rating { HStack(spacing: 2) { ForEach(1...5, id: \.self) { i in Image(systemName: i <= rating ? "star.fill" : "star") .font(.caption) .foregroundStyle(.white.opacity(i <= rating ? 1 : 0.4)) } } } Spacer() } .padding(.top, 16) } Spacer(minLength: 0) // Footer / branding HStack(spacing: 12) { Image("BrandMark") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 40, height: 40) .clipShape(RoundedRectangle(cornerRadius: 9, style: .continuous)) VStack(alignment: .leading, spacing: 2) { Text("Tracked with") .font(.caption2.weight(.medium)) .foregroundStyle(.white.opacity(0.7)) Text(appName) .font(.subheadline.weight(.bold)) .foregroundStyle(.white) } Spacer() if let qrCodeImage { Image(uiImage: qrCodeImage) .interpolation(.none) .resizable() .frame(width: 52, height: 52) .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: 7, style: .continuous)) } } .padding(.top, 20) } .padding(24) .frame(width: 340, height: 440) .background(ShareCardBackground()) .clipShape(RoundedRectangle(cornerRadius: 28, style: .continuous)) .overlay( RoundedRectangle(cornerRadius: 28, style: .continuous) .stroke(Color.white.opacity(0.12), lineWidth: 1) ) } }