New task feature (#2)
This PR contains the work done to implement the **New Task** feature, and to integrate it into the main context view of the app. Reviewed-on: rock-n-code/todos-app#2 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #2.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
extension ContentView {
|
||||
|
||||
/// View model for managing the logic for the content view.
|
||||
///
|
||||
/// This observable class encapsulates the state and business logic for the main content view.
|
||||
/// It follows the MVVM pattern to separate presentation logic from the view layer.
|
||||
///
|
||||
/// The view model manages:
|
||||
/// - Presentation state for the new task view within a sheet.
|
||||
@Observable
|
||||
class ViewModel {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// Whether the new task view should be shown.
|
||||
var newTaskShown: Bool
|
||||
|
||||
// MARK: Initialization
|
||||
|
||||
/// Initializes a new view model instance with default values.
|
||||
///
|
||||
/// The view model is initialized with:
|
||||
/// - New task view hidden
|
||||
init() {
|
||||
newTaskShown = false
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
/// Shows the new task view by setting the presentation state to true.
|
||||
func showNewTask() {
|
||||
newTaskShown = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
extension NewTaskView {
|
||||
|
||||
/// View model for managing the logic for creating todo tasks.
|
||||
///
|
||||
/// This observable class encapsulates the state and business logic for creating new todo tasks.
|
||||
/// It follows the MVVM pattern to separate presentation logic from the view layer.
|
||||
///
|
||||
/// The view model manages:
|
||||
/// - User input for task title, note, and due date
|
||||
/// - Form validation (ensuring title is not empty)
|
||||
/// - Saving the todo to SwiftData model context
|
||||
@Observable
|
||||
class ViewModel {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The title of the todo task.
|
||||
///
|
||||
/// This is a required field. The save button is disabled when this is empty.
|
||||
var title: String
|
||||
|
||||
/// A note providing additional details about the task, if required.
|
||||
///
|
||||
/// If left empty, the note will be stored as `nil` in the model.
|
||||
var note: String
|
||||
|
||||
/// The due date for the todo task.
|
||||
///
|
||||
/// Defaults to the current date when the view model is initialized.
|
||||
var due: Date
|
||||
|
||||
// MARK: Initialization
|
||||
|
||||
/// Initializes a new view model instance with default values.
|
||||
///
|
||||
/// The view model is initialized with:
|
||||
/// - Empty title
|
||||
/// - Empty note
|
||||
/// - Current date as due date
|
||||
init() {
|
||||
title = ""
|
||||
note = ""
|
||||
due = .init()
|
||||
}
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
/// Whether the confirmation button should be enabled.
|
||||
///
|
||||
/// Returns `true` when the title is not empty after trimming whitespace, `false` otherwise.
|
||||
var canConfirm: Bool {
|
||||
!title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
/// Saves a new todo task to the SwiftData model context.
|
||||
///
|
||||
/// This function creates a new `Todo` instance with the current property values and inserts it into the provided model context.
|
||||
/// The title and note are trimmed of leading and trailing whitespace before saving.
|
||||
/// The `note` property value is only included if it's not empty after trimming.
|
||||
///
|
||||
/// - Parameter modelContext: The SwiftData model context to insert a new todo task.
|
||||
func save(to modelContext: ModelContext) {
|
||||
let trimmedTitle = title.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let trimmedNote = note.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
let todo = Todo(
|
||||
title: trimmedTitle,
|
||||
note: trimmedNote.isEmpty ? nil : trimmedNote,
|
||||
due: due
|
||||
)
|
||||
|
||||
modelContext.insert(todo)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user