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 /// 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? /// 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 private var todos: [Todo] /// 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() // 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) { self._group = group } // 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 /// /// Cards are tappable and update the selected group binding for navigation split view. /// Task counts are fetched on-demand from the model context for each render. var body: some View { List( viewModel.groups, selection: $group ) { group in Card( group: group, count: viewModel.count( todos, for: group ) ) .listRowBackground(Color.clear) .listRowSeparator(.hidden) .tag(group) } .listStyle(.plain) .navigationTitle("view.task-group-list.navigation.title") .sensoryFeedback( .selection, trigger: group ) } } // MARK: - Previews #Preview( "Task group list with empty tasks", traits: .emptyContainer ) { @Previewable @State var group: TodoGroup? NavigationStack { TaskGroupListView($group) } } #Preview( "Task group list with sample tasks", traits: .sampleTasks ) { @Previewable @State var group: TodoGroup? NavigationStack { TaskGroupListView($group) } }