// // SportsTimeApp.swift // SportsTime // // Created by Trey Tartt on 1/6/26. // import SwiftUI import SwiftData @main struct SportsTimeApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([ // User data models SavedTrip.self, TripVote.self, UserPreferences.self, CachedSchedule.self, // Stadium progress models StadiumVisit.self, VisitPhotoMetadata.self, Achievement.self, CachedGameScore.self, // Canonical data models SyncState.self, CanonicalStadium.self, StadiumAlias.self, CanonicalTeam.self, TeamAlias.self, LeagueStructureModel.self, CanonicalGame.self, ]) let modelConfiguration = ModelConfiguration( schema: schema, isStoredInMemoryOnly: false, cloudKitDatabase: .none // Local only; CloudKit used separately for schedules ) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { BootstrappedContentView(modelContainer: sharedModelContainer) } .modelContainer(sharedModelContainer) } } // MARK: - Bootstrapped Content View /// Wraps the main content with bootstrap logic. /// Shows a loading indicator until bootstrap completes, then shows HomeView. struct BootstrappedContentView: View { let modelContainer: ModelContainer @State private var isBootstrapping = true @State private var bootstrapError: Error? var body: some View { Group { if isBootstrapping { BootstrapLoadingView() } else if let error = bootstrapError { BootstrapErrorView(error: error) { Task { await performBootstrap() } } } else { HomeView() } } .task { await performBootstrap() } } @MainActor private func performBootstrap() async { isBootstrapping = true bootstrapError = nil let context = modelContainer.mainContext let bootstrapService = BootstrapService() do { try await bootstrapService.bootstrapIfNeeded(context: context) isBootstrapping = false } catch { bootstrapError = error isBootstrapping = false } } } // MARK: - Bootstrap Loading View struct BootstrapLoadingView: View { var body: some View { VStack(spacing: 20) { ThemedSpinner(size: 50, lineWidth: 4) Text("Setting up SportsTime...") .font(.headline) .foregroundStyle(.secondary) } } } // MARK: - Bootstrap Error View struct BootstrapErrorView: View { let error: Error let onRetry: () -> Void var body: some View { VStack(spacing: 20) { Image(systemName: "exclamationmark.triangle.fill") .font(.system(size: 50)) .foregroundStyle(.orange) Text("Setup Failed") .font(.title2) .fontWeight(.semibold) Text(error.localizedDescription) .font(.subheadline) .foregroundStyle(.secondary) .multilineTextAlignment(.center) .padding(.horizontal) Button("Try Again") { onRetry() } .buttonStyle(.borderedProminent) } .padding() } }