1.0.6: Priority dishes, day rules, auto-assign CTA, tap-to-replace, export incomplete weeks, Sunday notification

- Dish.isPriority: mark dishes as priority; auto-assign gives them 2.5x weight
- Tag.dayRestriction: restrict tags to weekdays or weekend only
- Auto-assign CTA banner shown when there are empty slots (was hidden in context menu)
- Tap on filled slot opens picker to replace dish directly (no need to remove first)
- Export callout visible as soon as ≥1 slot is filled (not only when week is complete)
- WeekPlanShareView shows localized "TBD" / "Eating out" for empty/eating-out slots
- Second Sunday 17:00 push notification to plan next week
- DishDrawer sorts: priority first, then by historical usage, then alphabetically
- Search in SlotDishPickerSheet already shipped in 1.0.5 (verified ✓)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alexandrev-tibco
2026-04-30 00:00:53 +02:00
parent 92f97f855d
commit a4dfb38feb
22 changed files with 344 additions and 26 deletions
+6 -1
View File
@@ -6,6 +6,7 @@ final class DishViewModel: ObservableObject {
@Published var name: String = ""
@Published var descriptionText: String = ""
@Published var selectedTagIds: Set<UUID> = []
@Published var isPriority: Bool = false
@Published var showTagSelector: Bool = false
@Published var showDeleteAlert: Bool = false
@Published var showAssignedDeleteAlert: Bool = false
@@ -23,6 +24,7 @@ final class DishViewModel: ObservableObject {
name = dish.name
descriptionText = dish.descriptionText ?? ""
selectedTagIds = Set(dish.tagIds)
isPriority = dish.isPriority
}
func reset() {
@@ -30,6 +32,7 @@ final class DishViewModel: ObservableObject {
name = ""
descriptionText = ""
selectedTagIds = []
isPriority = false
}
func save(context: ModelContext) {
@@ -40,11 +43,13 @@ final class DishViewModel: ObservableObject {
dish.name = trimmedName
dish.descriptionText = descriptionText.isEmpty ? nil : descriptionText
dish.tagIds = Array(selectedTagIds)
dish.isPriority = isPriority
} else {
let dish = Dish(
name: trimmedName,
descriptionText: descriptionText.isEmpty ? nil : descriptionText,
tagIds: Array(selectedTagIds)
tagIds: Array(selectedTagIds),
isPriority: isPriority
)
context.insert(dish)
AnalyticsService.logDishAdded(tagCount: selectedTagIds.count)