import SwiftUI struct SettingsView: View { @EnvironmentObject var store: ConnectionStore var body: some View { ZStack { Color.white.ignoresSafeArea() ScrollView { VStack(spacing: AppTheme.sectionSpacing) { // LAN trigger hero section LANTriggerSection() // What to back up mediaSection // Quiet hours quietHoursSection // Notification section notificationSection Spacer(minLength: 40) } .padding(.horizontal, 20) .padding(.top, 20) } } .navigationTitle("Settings") .navigationBarTitleDisplayMode(.inline) } // MARK: Media section private var mediaSection: some View { VStack(alignment: .leading, spacing: 8) { Text("WHAT TO BACK UP") .font(AppTheme.smallFont) .foregroundColor(AppTheme.textSecondary) .padding(.leading, 4) VStack(spacing: 0) { ToggleRow(icon: "photo", title: "Photos", isOn: $store.backupFilter.includePhotos) Divider().padding(.leading, 44) ToggleRow(icon: "video", title: "Videos", isOn: $store.backupFilter.includeVideos) Divider().padding(.leading, 44) ToggleRow(icon: "camera.viewfinder", title: "Screenshots", isOn: $store.backupFilter.includeScreenshots) Divider().padding(.leading, 44) ToggleRow(icon: "rays", title: "RAW", isOn: $store.backupFilter.includeRAW) Divider().padding(.leading, 44) ToggleRow(icon: "doc.badge.clock", title: "New files only", subtitle: "Skip files already on NAS", isOn: $store.backupFilter.newFilesOnly) } .padding(.horizontal, 16) .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius)) .overlay(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius).stroke(AppTheme.cardBorder)) } } // MARK: Quiet hours private var quietHoursSection: some View { VStack(alignment: .leading, spacing: 8) { Text("QUIET HOURS") .font(AppTheme.smallFont) .foregroundColor(AppTheme.textSecondary) .padding(.leading, 4) VStack(spacing: 0) { ToggleRow(icon: "moon.fill", title: "Quiet hours", subtitle: "No auto-backup during this window", isOn: $store.quietHoursEnabled) if store.quietHoursEnabled { Divider().padding(.leading, 44) timePickerRow(label: "Start", hour: $store.quietHoursStart) Divider().padding(.leading, 44) timePickerRow(label: "End", hour: $store.quietHoursEnd) } Divider().padding(.leading, 44) ToggleRow(icon: "bolt.fill", title: "Only while charging", subtitle: "Preserve battery on large libraries", isOn: $store.chargingOnlyMode) } .padding(.horizontal, 16) .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius)) .overlay(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius).stroke(AppTheme.cardBorder)) } } private func timePickerRow(label: String, hour: Binding) -> some View { HStack { Text(label) .font(AppTheme.bodyFont) .foregroundColor(AppTheme.textPrimary) .frame(width: 80, alignment: .leading) Spacer() Picker(label, selection: hour) { ForEach(0..<24, id: \.self) { h in Text(String(format: "%02d:00", h)).tag(h) } } .pickerStyle(.menu) .tint(AppTheme.blue) } .padding(.vertical, 8) } // MARK: Notifications private var notificationSection: some View { VStack(alignment: .leading, spacing: 8) { Text("NOTIFICATIONS") .font(AppTheme.smallFont) .foregroundColor(AppTheme.textSecondary) .padding(.leading, 4) VStack(spacing: 0) { staticRow(icon: "bell.fill", title: "On start", value: "Off") Divider().padding(.leading, 44) staticRow(icon: "checkmark.circle.fill", title: "On complete", value: "On") Divider().padding(.leading, 44) staticRow(icon: "exclamationmark.triangle.fill", title: "On errors", value: "On") } .padding(.horizontal, 16) .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius)) .overlay(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius).stroke(AppTheme.cardBorder)) } } private func staticRow(icon: String, title: String, value: String) -> some View { HStack { Image(systemName: icon) .foregroundColor(AppTheme.blue) .frame(width: 28) Text(title) .font(AppTheme.bodyFont) .foregroundColor(AppTheme.textPrimary) Spacer() Text(value) .font(AppTheme.bodyFont) .foregroundColor(AppTheme.textSecondary) } .padding(.vertical, 12) } }