// // SettingsView.swift // SportsTime // import SwiftUI struct SettingsView: View { @State private var viewModel = SettingsViewModel() @State private var showResetConfirmation = false var body: some View { List { // Sports Preferences sportsSection // Travel Preferences travelSection // Game Preferences gamePreferencesSection // Notifications notificationsSection // Data Sync dataSection // About aboutSection // Reset resetSection } .navigationTitle("Settings") .alert("Reset Settings", isPresented: $showResetConfirmation) { Button("Cancel", role: .cancel) { } Button("Reset", role: .destructive) { viewModel.resetToDefaults() } } message: { Text("This will reset all settings to their default values.") } } // MARK: - Sports Section private var sportsSection: some View { Section { ForEach(Sport.supported) { sport in Toggle(isOn: Binding( get: { viewModel.selectedSports.contains(sport) }, set: { _ in viewModel.toggleSport(sport) } )) { Label { Text(sport.displayName) } icon: { Image(systemName: sport.iconName) .foregroundStyle(sportColor(for: sport)) } } } } header: { Text("Favorite Sports") } footer: { Text("Selected sports will be shown by default in schedules and trip planning.") } } // MARK: - Travel Section private var travelSection: some View { Section { Stepper(value: $viewModel.maxDrivingHoursPerDay, in: 2...12) { HStack { Text("Max Driving Per Day") Spacer() Text("\(viewModel.maxDrivingHoursPerDay) hours") .foregroundStyle(.secondary) } } } header: { Text("Travel Preferences") } footer: { Text("Trips will be optimized to keep daily driving within this limit.") } } // MARK: - Game Preferences Section private var gamePreferencesSection: some View { Section { Picker("Preferred Game Time", selection: $viewModel.preferredGameTime) { ForEach(PreferredGameTime.allCases) { time in VStack(alignment: .leading) { Text(time.displayName) } .tag(time) } } Toggle("Include Playoff Games", isOn: $viewModel.includePlayoffGames) } header: { Text("Game Preferences") } footer: { Text("These preferences affect trip optimization.") } } // MARK: - Notifications Section private var notificationsSection: some View { Section { Toggle("Schedule Updates", isOn: $viewModel.notificationsEnabled) } header: { Text("Notifications") } footer: { Text("Get notified when games in your trips are rescheduled.") } } // MARK: - Data Section private var dataSection: some View { Section { Button { Task { await viewModel.syncSchedules() } } label: { HStack { Label("Sync Schedules", systemImage: "arrow.triangle.2.circlepath") Spacer() if viewModel.isSyncing { ProgressView() } } } .disabled(viewModel.isSyncing) if let lastSync = viewModel.lastSyncDate { HStack { Text("Last Sync") Spacer() Text(lastSync, style: .relative) .foregroundStyle(.secondary) } } if let error = viewModel.syncError { HStack { Image(systemName: "exclamationmark.triangle") .foregroundStyle(.red) Text(error) .font(.caption) .foregroundStyle(.red) } } } header: { Text("Data") } footer: { #if targetEnvironment(simulator) Text("Using stub data (Simulator mode)") #else Text("Schedule data is synced from CloudKit.") #endif } } // MARK: - About Section private var aboutSection: some View { Section { HStack { Text("Version") Spacer() Text("\(viewModel.appVersion) (\(viewModel.buildNumber))") .foregroundStyle(.secondary) } Link(destination: URL(string: "https://sportstime.app/privacy")!) { Label("Privacy Policy", systemImage: "hand.raised") } Link(destination: URL(string: "https://sportstime.app/terms")!) { Label("Terms of Service", systemImage: "doc.text") } Link(destination: URL(string: "mailto:support@sportstime.app")!) { Label("Contact Support", systemImage: "envelope") } } header: { Text("About") } } // MARK: - Reset Section private var resetSection: some View { Section { Button(role: .destructive) { showResetConfirmation = true } label: { Label("Reset to Defaults", systemImage: "arrow.counterclockwise") } } } // MARK: - Helpers private func sportColor(for sport: Sport) -> Color { switch sport { case .mlb: return .red case .nba: return .orange case .nhl: return .blue case .nfl: return .green case .mls: return .purple } } } #Preview { NavigationStack { SettingsView() } }