90 lines
2.6 KiB
Swift
90 lines
2.6 KiB
Swift
import SwiftUI
|
|
import SwiftData
|
|
|
|
@MainActor
|
|
final class DishViewModel: ObservableObject {
|
|
@Published var name: String = ""
|
|
@Published var descriptionText: String = ""
|
|
@Published var selectedTagIds: Set<UUID> = []
|
|
@Published var showTagSelector: Bool = false
|
|
@Published var showDeleteAlert: Bool = false
|
|
@Published var showAssignedDeleteAlert: Bool = false
|
|
|
|
var editingDish: Dish?
|
|
|
|
var isEditing: Bool { editingDish != nil }
|
|
|
|
var isValid: Bool {
|
|
!name.trimmingCharacters(in: .whitespaces).isEmpty
|
|
}
|
|
|
|
func loadDish(_ dish: Dish) {
|
|
editingDish = dish
|
|
name = dish.name
|
|
descriptionText = dish.descriptionText ?? ""
|
|
selectedTagIds = Set(dish.tagIds)
|
|
}
|
|
|
|
func reset() {
|
|
editingDish = nil
|
|
name = ""
|
|
descriptionText = ""
|
|
selectedTagIds = []
|
|
}
|
|
|
|
func save(context: ModelContext) {
|
|
let trimmedName = name.trimmingCharacters(in: .whitespaces)
|
|
guard !trimmedName.isEmpty else { return }
|
|
|
|
if let dish = editingDish {
|
|
dish.name = trimmedName
|
|
dish.descriptionText = descriptionText.isEmpty ? nil : descriptionText
|
|
dish.tagIds = Array(selectedTagIds)
|
|
} else {
|
|
let dish = Dish(
|
|
name: trimmedName,
|
|
descriptionText: descriptionText.isEmpty ? nil : descriptionText,
|
|
tagIds: Array(selectedTagIds)
|
|
)
|
|
context.insert(dish)
|
|
}
|
|
|
|
try? context.save()
|
|
reset()
|
|
}
|
|
|
|
func deleteDish(context: ModelContext) -> Bool {
|
|
guard let dish = editingDish else { return false }
|
|
|
|
if isDishAssignedInCurrentWeek(dishId: dish.id, context: context) {
|
|
showAssignedDeleteAlert = true
|
|
return false
|
|
}
|
|
|
|
context.delete(dish)
|
|
try? context.save()
|
|
reset()
|
|
return true
|
|
}
|
|
|
|
func canDelete(currentPlan: WeekPlan?) -> Bool {
|
|
guard let dish = editingDish, let plan = currentPlan else { return true }
|
|
return !plan.slots.contains { $0.dishId == dish.id }
|
|
}
|
|
|
|
private func isDishAssignedInCurrentWeek(dishId: UUID, context: ModelContext) -> Bool {
|
|
let currentWeekStart = Date().startOfWeek()
|
|
let descriptor = FetchDescriptor<WeekPlan>(
|
|
predicate: #Predicate<WeekPlan> { plan in
|
|
plan.weekStartDate == currentWeekStart
|
|
}
|
|
)
|
|
|
|
guard let currentPlan = try? context.fetch(descriptor).first else {
|
|
return false
|
|
}
|
|
|
|
return currentPlan.slots.contains { $0.dishId == dishId }
|
|
}
|
|
}
|