import SwiftUI struct SettingsView: View { @EnvironmentObject var store: ConnectionStore var body: some View { ZStack { Color.white.ignoresSafeArea() ScrollView { VStack(spacing: AppTheme.sectionGap) { LANTriggerSection() mediaSection quietHoursSection notificationSection } .padding(.horizontal, AppTheme.hPad) .padding(.top, 20) .padding(.bottom, 48) } } .navigationTitle("Settings") .navigationBarTitleDisplayMode(.inline) } // MARK: — Media private var mediaSection: some View { VStack(alignment: .leading, spacing: 8) { sectionLabel("WHAT TO BACK UP") VStack(spacing: 0) { ToggleRow(icon: "photo", title: "Photos", isOn: $store.backupFilter.includePhotos) hairline ToggleRow(icon: "video", title: "Videos", isOn: $store.backupFilter.includeVideos) hairline ToggleRow(icon: "camera.viewfinder", title: "Screenshots", isOn: $store.backupFilter.includeScreenshots) hairline ToggleRow(icon: "rays", title: "RAW", isOn: $store.backupFilter.includeRAW) hairline ToggleRow(icon: "doc.badge.clock", title: "New files only", subtitle: "Skip files already on NAS", isOn: $store.backupFilter.newFilesOnly) } .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous)) .shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2) } } // MARK: — Quiet hours private var quietHoursSection: some View { VStack(alignment: .leading, spacing: 8) { sectionLabel("QUIET HOURS") VStack(spacing: 0) { ToggleRow(icon: "moon", title: "Quiet hours", subtitle: "No auto-backup during this window", isOn: $store.quietHoursEnabled) if store.quietHoursEnabled { hairline timePickerRow(label: "Start", hour: $store.quietHoursStart) hairline timePickerRow(label: "End", hour: $store.quietHoursEnd) } hairline ToggleRow(icon: "bolt", title: "Only while charging", subtitle: "Preserve battery on large libraries", isOn: $store.chargingOnlyMode) } .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous)) .shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2) .animation(.spring(response: 0.3, dampingFraction: 0.8), value: store.quietHoursEnabled) } } private func timePickerRow(label: String, hour: Binding) -> some View { HStack { Text(label) .font(AppTheme.body()) .foregroundStyle(AppTheme.ink) Spacer() Picker(label, selection: hour) { ForEach(0..<24, id: \.self) { h in Text(String(format: "%02d:00", h)).tag(h) } } .pickerStyle(.menu) .tint(AppTheme.inkSecondary) } .padding(.horizontal, AppTheme.cardPad) .padding(.vertical, 12) } // MARK: — Notifications private var notificationSection: some View { VStack(alignment: .leading, spacing: 8) { sectionLabel("NOTIFICATIONS") VStack(spacing: 0) { notifRow(icon: "bell", title: "On start", value: "Off") hairline notifRow(icon: "checkmark.circle", title: "On complete", value: "On") hairline notifRow(icon: "exclamationmark.triangle", title: "On errors", value: "On") } .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous)) .shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2) } } private func notifRow(icon: String, title: String, value: String) -> some View { HStack(spacing: 12) { Image(systemName: icon) .font(.system(size: 14, weight: .regular)) .foregroundStyle(AppTheme.inkSecondary) .frame(width: 20) Text(title) .font(AppTheme.body()) .foregroundStyle(AppTheme.ink) Spacer() Text(value) .font(AppTheme.caption()) .foregroundStyle(AppTheme.inkTertiary) } .padding(.horizontal, AppTheme.cardPad) .padding(.vertical, 14) } private var hairline: some View { Rectangle() .fill(AppTheme.separator) .frame(height: 0.5) .padding(.leading, AppTheme.cardPad) } }