// // SettingsView.swift // SportsTime // import SwiftUI struct SettingsView: View { @Environment(\.colorScheme) private var colorScheme @State private var viewModel = SettingsViewModel() @State private var showResetConfirmation = false var body: some View { List { // Theme Selection themeSection // Sports Preferences sportsSection // Travel Preferences travelSection // Data Sync dataSection // About aboutSection // Reset resetSection } .scrollContentBackground(.hidden) .themedBackground() .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: - Theme Section private var themeSection: some View { Section { ForEach(AppTheme.allCases) { theme in Button { withAnimation(.easeInOut(duration: 0.2)) { viewModel.selectedTheme = theme } } label: { HStack(spacing: 12) { // Color preview circles HStack(spacing: -6) { ForEach(Array(theme.previewColors.enumerated()), id: \.offset) { _, color in Circle() .fill(color) .frame(width: 24, height: 24) .overlay( Circle() .stroke(Color.primary.opacity(0.1), lineWidth: 1) ) } } VStack(alignment: .leading, spacing: 2) { Text(theme.displayName) .font(.body) .foregroundStyle(.primary) Text(theme.description) .font(.caption) .foregroundStyle(.secondary) } Spacer() if viewModel.selectedTheme == theme { Image(systemName: "checkmark.circle.fill") .foregroundStyle(Theme.warmOrange) .font(.title3) } } .contentShape(Rectangle()) } .buttonStyle(.plain) } } header: { Text("Theme") } footer: { Text("Choose a color scheme for the app.") } .listRowBackground(Theme.cardBackground(colorScheme)) } // 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.") } .listRowBackground(Theme.cardBackground(colorScheme)) } // MARK: - Travel Section private var travelSection: some View { Section { VStack(alignment: .leading, spacing: 8) { HStack { Text("Max Driving Per Day") Spacer() Text("\(viewModel.maxDrivingHoursPerDay) hours") .foregroundStyle(.secondary) } Slider( value: Binding( get: { Double(viewModel.maxDrivingHoursPerDay) }, set: { viewModel.maxDrivingHoursPerDay = Int($0) } ), in: 2...12, step: 1 ) } } header: { Text("Travel Preferences") } footer: { Text("Trips will be optimized to keep daily driving within this limit.") } .listRowBackground(Theme.cardBackground(colorScheme)) } // 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 { ThemedSpinnerCompact(size: 18) } } } .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 } .listRowBackground(Theme.cardBackground(colorScheme)) } // 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") } .listRowBackground(Theme.cardBackground(colorScheme)) } // MARK: - Reset Section private var resetSection: some View { Section { Button(role: .destructive) { showResetConfirmation = true } label: { Label("Reset to Defaults", systemImage: "arrow.counterclockwise") } } .listRowBackground(Theme.cardBackground(colorScheme)) } // MARK: - Helpers private func sportColor(for sport: Sport) -> Color { sport.themeColor } } #Preview { NavigationStack { SettingsView() } }