// // PaywallView.swift // SportsTime // // Full-screen paywall for Pro subscription using SubscriptionStoreView. // import SwiftUI import StoreKit struct PaywallView: View { @Environment(\.dismiss) private var dismiss @Environment(\.colorScheme) private var colorScheme private let storeManager = StoreManager.shared let source: String init(source: String = "unknown") { self.source = source } var body: some View { SubscriptionStoreView(subscriptions: storeManager.products.filter { $0.subscription != nil }) { VStack(spacing: Theme.Spacing.md) { Image(systemName: "star.circle.fill") .font(.system(size: 60)) .foregroundStyle(Theme.warmOrange) Text("Upgrade to Pro") .font(.largeTitle.bold()) .foregroundStyle(Theme.textPrimary(colorScheme)) Text("Unlock the full SportsTime experience") .font(.body) .foregroundStyle(Theme.textSecondary(colorScheme)) HStack(spacing: Theme.Spacing.lg) { featurePill(icon: "infinity", text: "Unlimited Trips") featurePill(icon: "doc.fill", text: "PDF Export") featurePill(icon: "trophy.fill", text: "Progress") } .padding(.top, Theme.Spacing.sm) } .padding(Theme.Spacing.lg) } .storeButton(.visible, for: .restorePurchases) .subscriptionStoreControlStyle(.prominentPicker) .subscriptionStoreButtonLabel(.displayName.multiline) .onInAppPurchaseStart { product in AnalyticsManager.shared.trackPurchaseStarted(productId: product.id, source: source) } .onInAppPurchaseCompletion { product, result in switch result { case .success(.success(_)): AnalyticsManager.shared.trackPurchaseCompleted(productId: product.id, source: source) Task { @MainActor in await storeManager.updateEntitlements() storeManager.trackSubscriptionAnalytics(source: "purchase_success") } dismiss() case .success(.userCancelled): AnalyticsManager.shared.trackPurchaseFailed(productId: product.id, source: source, error: "user_cancelled") case .success(.pending): AnalyticsManager.shared.trackPurchaseFailed(productId: product.id, source: source, error: "pending") case .failure(let error): AnalyticsManager.shared.trackPurchaseFailed(productId: product.id, source: source, error: error.localizedDescription) @unknown default: AnalyticsManager.shared.trackPurchaseFailed(productId: product.id, source: source, error: "unknown_result") } } .task { await storeManager.loadProducts() } .onAppear { AnalyticsManager.shared.trackPaywallViewed(source: source) } } private func featurePill(icon: String, text: String) -> some View { HStack(spacing: 4) { Image(systemName: icon) .font(.system(size: 11)) Text(text) .font(.caption2) } .foregroundStyle(Theme.textMuted(colorScheme)) .padding(.horizontal, 10) .padding(.vertical, 6) .background(Theme.warmOrange.opacity(0.08), in: Capsule()) } } #Preview { PaywallView() }