// // ProgressCardGenerator.swift // SportsTime // // Generates shareable stadium progress cards. // import SwiftUI import UIKit // MARK: - Progress Share Content struct ProgressShareContent: ShareableContent { let progress: LeagueProgress let tripCount: Int let username: String? var cardType: ShareCardType { .stadiumProgress } @MainActor func render(theme: ShareTheme) async throws -> UIImage { let mapGenerator = ShareMapSnapshotGenerator() let mapSnapshot = await mapGenerator.generateProgressMap( visited: progress.stadiumsVisited, remaining: progress.stadiumsRemaining, theme: theme ) let cardView = ProgressCardView( progress: progress, tripCount: tripCount, username: username, theme: theme, mapSnapshot: mapSnapshot ) let renderer = ImageRenderer(content: cardView) renderer.scale = 3.0 guard let image = renderer.uiImage else { throw ShareError.renderingFailed } return image } } // MARK: - Progress Card View private struct ProgressCardView: View { let progress: LeagueProgress let tripCount: Int let username: String? let theme: ShareTheme let mapSnapshot: UIImage? var body: some View { ZStack { ShareCardBackground(theme: theme) VStack(spacing: 40) { ShareCardHeader( title: "\(progress.sport.displayName) Stadium Quest", sport: progress.sport, theme: theme ) Spacer() // Progress ring ShareProgressRing( current: progress.visitedStadiums, total: progress.totalStadiums, theme: theme ) Text("\(Int(progress.completionPercentage))% Complete") .font(.system(size: 28, weight: .medium)) .foregroundStyle(theme.secondaryTextColor) // Stats row ShareStatsRow( stats: [ (value: "\(progress.visitedStadiums)", label: "visited"), (value: "\(progress.totalStadiums - progress.visitedStadiums)", label: "remain"), (value: "\(tripCount)", label: "trips") ], theme: theme ) // Map if let snapshot = mapSnapshot { Image(uiImage: snapshot) .resizable() .aspectRatio(contentMode: .fit) .frame(maxWidth: 960) .clipShape(RoundedRectangle(cornerRadius: 20)) .overlay { RoundedRectangle(cornerRadius: 20) .stroke(theme.accentColor.opacity(0.3), lineWidth: 2) } } Spacer() ShareCardFooter(theme: theme, username: username) } .padding(ShareCardDimensions.padding) } .frame( width: ShareCardDimensions.cardSize.width, height: ShareCardDimensions.cardSize.height ) } }