93 lines
4.1 KiB
Swift
93 lines
4.1 KiB
Swift
// ── Quick Timer Sheet ──────────────────────────────────────────
|
|
// Bottom sheet with one-tap preset timers
|
|
|
|
import SwiftUI
|
|
|
|
struct QuickTimerSheet: View {
|
|
@EnvironmentObject var store: TimerStore
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
private let presets: [(String, Int, String, UrgencyLevel)] = [
|
|
("1 min", 1, "timer", .gentle),
|
|
("3 min", 3, "timer", .gentle),
|
|
("5 min", 5, "timer", .gentle),
|
|
("10 min", 10, "timer", .standard),
|
|
("15 min", 15, "timer", .standard),
|
|
("20 min", 20, "timer", .standard),
|
|
("25 min", 25, "Pomodoro", .standard),
|
|
("30 min", 30, "timer", .standard),
|
|
("45 min", 45, "timer", .important),
|
|
("1 hour", 60, "timer", .important),
|
|
("90 min", 90, "timer", .important),
|
|
("2 hours", 120, "timer", .important),
|
|
]
|
|
|
|
let columns = [
|
|
GridItem(.flexible(), spacing: CMSpacing.md),
|
|
GridItem(.flexible(), spacing: CMSpacing.md),
|
|
GridItem(.flexible(), spacing: CMSpacing.md),
|
|
]
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
ZStack {
|
|
CMColors.bg.ignoresSafeArea()
|
|
|
|
ScrollView {
|
|
LazyVGrid(columns: columns, spacing: CMSpacing.md) {
|
|
ForEach(presets, id: \.0) { label, minutes, name, urgency in
|
|
Button {
|
|
HapticEngine.tap()
|
|
let _ = store.addCountdown(CreateCountdownParams(
|
|
label: "\(label) \(name)",
|
|
durationSeconds: TimeInterval(minutes * 60),
|
|
urgency: urgency,
|
|
cascade: CascadeConfig(
|
|
preset: minutes >= 30 ? .light : .minimal,
|
|
intervals: []
|
|
)
|
|
))
|
|
dismiss()
|
|
} label: {
|
|
VStack(spacing: CMSpacing.xs) {
|
|
Text(label)
|
|
.font(CMFonts.mono(size: 18, weight: .semibold))
|
|
.foregroundStyle(CMColors.text)
|
|
|
|
// Time reference
|
|
if let ref = getTimeReference(minutes: minutes) {
|
|
Text(ref.replacingOccurrences(of: "About as long as ", with: ""))
|
|
.font(CMFonts.body(size: 10))
|
|
.foregroundStyle(CMColors.textMuted)
|
|
.lineLimit(1)
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical, CMSpacing.lg)
|
|
.background(CMColors.surface)
|
|
.clipShape(RoundedRectangle(cornerRadius: CMRadius.md))
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: CMRadius.md)
|
|
.stroke(CMColors.border, lineWidth: 1)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
.padding(CMSpacing.lg)
|
|
}
|
|
}
|
|
.navigationTitle("Quick Timer")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Cancel") { dismiss() }
|
|
.foregroundStyle(CMColors.textSecondary)
|
|
}
|
|
}
|
|
.toolbarBackground(CMColors.surface, for: .navigationBar)
|
|
.toolbarColorScheme(.dark, for: .navigationBar)
|
|
}
|
|
.presentationDetents([.medium, .large])
|
|
}
|
|
}
|