Files

110 lines
3.1 KiB
Swift
Raw Permalink Normal View History

2026-02-10 02:22:41 +00:00
import SwiftData
import SwiftUI
/// A view that displays todo tasks grouped by date and completion categories.
///
/// This view serves as the main interface for browsing tasks organized into four groups:
/// - **Today**: Tasks due today that are not yet completed
/// - **Upcoming**: Tasks due in the future that are not yet completed
/// - **Overdue**: Tasks due in the past that are not yet completed
/// - **Completed**: Tasks that have been marked as done
struct TaskGroupListView: View {
// MARK: Properties
2026-02-12 03:55:17 +00:00
/// Binding to the currently selected todo task group.
///
/// When provided, the view will use this binding for navigation split view selection.
@Binding
private var group: TodoGroup?
2026-02-10 02:22:41 +00:00
/// Query to monitor all todo tasks for changes.
///
/// This query triggers view updates whenever todo tasks are inserted, updated, or deleted,
/// ensuring the task counts displayed in the view remain accurate.
@Query
2026-02-12 03:55:17 +00:00
private var todos: [Todo]
2026-02-10 02:22:41 +00:00
/// The view model managing the state and logic for this view.
///
/// Handles task counting and provides access to all task groups.
/// Initialized with the default calendar for date calculations.
@State
private var viewModel = ViewModel()
2026-02-12 03:55:17 +00:00
// MARK: Initializers
/// Creates a task group list view with a binding to the selected group.
///
/// This initializer configures the view for use in a navigation split view,
/// where the binding tracks which task group is currently selected in the sidebar.
///
/// - Parameter group: A binding to the currently selected task group.
init(_ group: Binding<TodoGroup?>) {
self._group = group
}
2026-02-10 02:22:41 +00:00
// MARK: Body
/// The content and behavior of the view.
///
/// Displays a scrollable vertical list of task group cards. Each card shows:
/// - The group's icon in its associated color
/// - The group's title
/// - The current count of tasks in that group
///
2026-02-12 03:55:17 +00:00
/// Cards are tappable and update the selected group binding for navigation split view.
2026-02-10 02:22:41 +00:00
/// Task counts are fetched on-demand from the model context for each render.
var body: some View {
2026-02-12 03:55:17 +00:00
List(
viewModel.groups,
selection: $group
) { group in
Card(
group: group,
count: viewModel.count(
todos,
for: group
)
)
.listRowBackground(Color.clear)
.listRowSeparator(.hidden)
.tag(group)
2026-02-10 02:22:41 +00:00
}
2026-02-12 03:55:17 +00:00
.listStyle(.plain)
2026-02-10 02:22:41 +00:00
.navigationTitle("view.task-group-list.navigation.title")
2026-02-12 03:55:17 +00:00
.sensoryFeedback(
.selection,
trigger: group
)
2026-02-10 02:22:41 +00:00
}
}
// MARK: - Previews
#Preview(
"Task group list with empty tasks",
traits: .emptyContainer
) {
2026-02-12 03:55:17 +00:00
@Previewable
@State
var group: TodoGroup?
2026-02-10 02:22:41 +00:00
NavigationStack {
2026-02-12 03:55:17 +00:00
TaskGroupListView($group)
2026-02-10 02:22:41 +00:00
}
}
#Preview(
"Task group list with sample tasks",
traits: .sampleTasks
) {
2026-02-12 03:55:17 +00:00
@Previewable
@State
var group: TodoGroup?
2026-02-10 02:22:41 +00:00
NavigationStack {
2026-02-12 03:55:17 +00:00
TaskGroupListView($group)
2026-02-10 02:22:41 +00:00
}
}