reglas: plato fijo por dia y comida (ej. tortilla los viernes de cena)

- Dish.fixedDayOfWeek/fixedMealType (opcionales, aditivos para CloudKit)
- Toggle + pickers de dia/comida en el formulario de plato
- AutocompleteEngine: pre-pasada que asigna los platos fijos a su hueco
  antes del bucle MRV, de modo que cuentan para el resto de reglas
- Evento analytics dish_fixed_slot_set; strings en 6 idiomas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
This commit is contained in:
alexandrev-tibco
2026-09-01 11:22:34 +02:00
parent 47daab9e51
commit 7193234024
10 changed files with 120 additions and 2 deletions
+54
View File
@@ -27,6 +27,12 @@ struct DishFormView: View {
(allSettings.first?.languageEnum ?? .system).resolved()
}
/// Localized weekday name for the app's 0=Monday 6=Sunday convention.
static func weekdayName(_ day: Int) -> String {
let symbols = Calendar.current.standaloneWeekdaySymbols // [0]=Sunday
return symbols[(day + 1) % 7].capitalized
}
private var reachedFreeDishLimit: Bool {
guard let settings = allSettings.first else { return false }
if viewModel.isEditing { return false }
@@ -290,6 +296,54 @@ struct DishFormView: View {
.background(Color.mealMoodSurface)
.cornerRadius(14)
// Fixed-slot rule ("tortilla every Friday dinner")
VStack(alignment: .leading, spacing: 10) {
Toggle(isOn: Binding(
get: { viewModel.hasFixedSlot },
set: { viewModel.hasFixedSlot = $0 }
)) {
VStack(alignment: .leading, spacing: 2) {
HStack(spacing: 6) {
Image(systemName: "pin.fill")
.foregroundColor(.mealMoodCoral)
.font(.system(size: 13))
Text("dish_fixed_slot")
.font(.mealMoodBodyBold)
.foregroundColor(.mealMoodTextPrimary)
}
Text("dish_fixed_slot_desc")
.font(.mealMoodCaption)
.foregroundColor(.mealMoodTextSecondary)
}
}
.tint(.mealMoodCoral)
if viewModel.hasFixedSlot {
HStack(spacing: 12) {
Picker("dish_fixed_slot_day", selection: Binding(
get: { viewModel.fixedDayOfWeek },
set: { viewModel.fixedDayOfWeek = $0 }
)) {
ForEach(0..<7, id: \.self) { day in
Text(Self.weekdayName(day)).tag(day)
}
}
Picker("dish_fixed_slot_meal", selection: Binding(
get: { viewModel.fixedMealType },
set: { viewModel.fixedMealType = $0 }
)) {
ForEach(allSettings.first?.activeMealTypes ?? MealType.allCases, id: \.self) { meal in
Text(LocalizedStringKey(meal.localizedKey)).tag(meal)
}
}
}
.pickerStyle(.menu)
.tint(.mealMoodCoral)
}
}
.padding(16)
.background(Color.mealMoodSurface)
.cornerRadius(14)
// Delete button (edit mode only)
if viewModel.isEditing {