161 lines
7.1 KiB
Swift
161 lines
7.1 KiB
Swift
// ── Settings View ──────────────────────────────────────────────
|
|
// Preferences, categories, sounds, about
|
|
|
|
import SwiftUI
|
|
|
|
struct SettingsView: View {
|
|
@EnvironmentObject var store: TimerStore
|
|
@EnvironmentObject var notificationManager: CMNotificationManager
|
|
|
|
@AppStorage("cm_defaultUrgency") private var defaultUrgency = "standard"
|
|
@AppStorage("cm_defaultCascade") private var defaultCascade = "standard"
|
|
@AppStorage("cm_hapticEnabled") private var hapticEnabled = true
|
|
@AppStorage("cm_soundEnabled") private var soundEnabled = true
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
ZStack {
|
|
CMColors.bg.ignoresSafeArea()
|
|
|
|
List {
|
|
// Notifications
|
|
Section {
|
|
HStack {
|
|
Label("Notifications", systemImage: "bell.fill")
|
|
.foregroundStyle(CMColors.text)
|
|
Spacer()
|
|
if notificationManager.isAuthorized {
|
|
Text("Enabled")
|
|
.font(CMFonts.body(size: 13))
|
|
.foregroundStyle(CMColors.success)
|
|
} else {
|
|
Button("Enable") {
|
|
Task {
|
|
await notificationManager.requestPermission()
|
|
}
|
|
}
|
|
.font(CMFonts.body(size: 13, weight: .semibold))
|
|
.foregroundStyle(CMColors.accent)
|
|
}
|
|
}
|
|
|
|
Toggle(isOn: $hapticEnabled) {
|
|
Label("Haptic Feedback", systemImage: "iphone.radiowaves.left.and.right")
|
|
.foregroundStyle(CMColors.text)
|
|
}
|
|
.tint(CMColors.accent)
|
|
|
|
Toggle(isOn: $soundEnabled) {
|
|
Label("Sound", systemImage: "speaker.wave.2.fill")
|
|
.foregroundStyle(CMColors.text)
|
|
}
|
|
.tint(CMColors.accent)
|
|
} header: {
|
|
Text("Notifications & Feedback")
|
|
.foregroundStyle(CMColors.textMuted)
|
|
}
|
|
.listRowBackground(CMColors.surface)
|
|
|
|
// Defaults
|
|
Section {
|
|
Picker(selection: $defaultUrgency) {
|
|
ForEach(UrgencyLevel.allCases) { level in
|
|
HStack {
|
|
Circle()
|
|
.fill(CMColors.urgencyColor(level))
|
|
.frame(width: 8, height: 8)
|
|
Text(getUrgencyConfig(level).label)
|
|
}
|
|
.tag(level.rawValue)
|
|
}
|
|
} label: {
|
|
Label("Default Urgency", systemImage: "exclamationmark.triangle.fill")
|
|
.foregroundStyle(CMColors.text)
|
|
}
|
|
|
|
Picker(selection: $defaultCascade) {
|
|
ForEach(CascadePreset.allCases.filter { $0 != .custom }) { preset in
|
|
Text(preset.label).tag(preset.rawValue)
|
|
}
|
|
} label: {
|
|
Label("Default Cascade", systemImage: "arrow.down.forward.and.arrow.up.backward")
|
|
.foregroundStyle(CMColors.text)
|
|
}
|
|
} header: {
|
|
Text("Defaults")
|
|
.foregroundStyle(CMColors.textMuted)
|
|
}
|
|
.listRowBackground(CMColors.surface)
|
|
|
|
// Data
|
|
Section {
|
|
HStack {
|
|
Label("Total Timers", systemImage: "number")
|
|
.foregroundStyle(CMColors.text)
|
|
Spacer()
|
|
Text("\(store.timers.count)")
|
|
.font(CMFonts.mono(size: 14))
|
|
.foregroundStyle(CMColors.textSecondary)
|
|
}
|
|
|
|
Button {
|
|
store.timers.removeAll { [.completed, .dismissed].contains($0.state) }
|
|
} label: {
|
|
Label("Clear History", systemImage: "trash")
|
|
.foregroundStyle(CMColors.error)
|
|
}
|
|
|
|
Button {
|
|
store.timers.removeAll()
|
|
CMNotificationManager.shared.removeAllNotifications()
|
|
} label: {
|
|
Label("Delete All Timers", systemImage: "trash.fill")
|
|
.foregroundStyle(CMColors.error)
|
|
}
|
|
} header: {
|
|
Text("Data")
|
|
.foregroundStyle(CMColors.textMuted)
|
|
}
|
|
.listRowBackground(CMColors.surface)
|
|
|
|
// About
|
|
Section {
|
|
HStack {
|
|
Label("Version", systemImage: "info.circle")
|
|
.foregroundStyle(CMColors.text)
|
|
Spacer()
|
|
Text("1.0.0 (Phase 3)")
|
|
.font(CMFonts.body(size: 13))
|
|
.foregroundStyle(CMColors.textMuted)
|
|
}
|
|
|
|
HStack {
|
|
Label("Product ID", systemImage: "barcode")
|
|
.foregroundStyle(CMColors.text)
|
|
Spacer()
|
|
Text("chronomind")
|
|
.font(CMFonts.mono(size: 13))
|
|
.foregroundStyle(CMColors.textMuted)
|
|
}
|
|
|
|
Link(destination: URL(string: "https://chronomind.app/privacy")!) {
|
|
Label("Privacy Policy", systemImage: "hand.raised.fill")
|
|
.foregroundStyle(CMColors.text)
|
|
}
|
|
} header: {
|
|
Text("About")
|
|
.foregroundStyle(CMColors.textMuted)
|
|
}
|
|
.listRowBackground(CMColors.surface)
|
|
}
|
|
.scrollContentBackground(.hidden)
|
|
.listStyle(.insetGrouped)
|
|
}
|
|
.navigationTitle("Settings")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbarBackground(CMColors.surface, for: .navigationBar)
|
|
.toolbarColorScheme(.dark, for: .navigationBar)
|
|
}
|
|
}
|
|
}
|