Files
FamilyMealPlanner/MealMood/Components/EmptySlotView.swift
T
alexandrev-tibco 6fe16d8e29 huecos sin planificar y exclusiones en la lista de la compra
- MealSlot.isSkipped: opcion "No planificar esta comida" en el picker de
  hueco vacio — cuenta como resuelto (semana completa, notificaciones,
  stats) y el autocompletado lo respeta; vista gris con guion, tap para
  desmarcar; viaja en undo, snapshot KV (junto con isEatingOut, que
  faltaba en el payload) y exports (— en imagen, omitido en texto)
- ShoppingItem.isDismissed: "Ya lo tengo" por ingrediente (swipe
  izquierdo) y "Ya esta hecho" por plato entero (boton en la cabecera de
  su seccion); van a la seccion "Ya en casa" con restauracion de un tap,
  y quedan fuera del export de texto. No se borran porque reconcile los
  recrearia
- Esquema CloudKit Development: CD_isSkipped, CD_isDismissed y el record
  type CD_ShoppingItem entero, que no existia — la lista de la compra no
  estaba sincronizando entre dispositivos (mismo bug que photoData)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 16:16:34 +02:00

103 lines
3.2 KiB
Swift

import SwiftUI
struct EmptySlotView: View {
let mealType: MealType
let isDropTarget: Bool
let isValidDrop: Bool?
init(mealType: MealType, isDropTarget: Bool = false, isValidDrop: Bool? = nil) {
self.mealType = mealType
self.isDropTarget = isDropTarget
self.isValidDrop = isValidDrop
}
var body: some View {
VStack(spacing: 6) {
Image(systemName: mealType.icon)
.font(.system(size: 20))
.foregroundColor(Color(hex: "#C4C4C4"))
Text(LocalizedStringKey(mealType.rawValue))
.font(.mealMoodCaption)
.foregroundColor(.mealMoodTextSecondary)
}
.frame(maxWidth: .infinity, minHeight: 80)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(Color(hex: "#F9F9F9"))
.overlay(
RoundedRectangle(cornerRadius: 12)
.strokeBorder(
style: StrokeStyle(lineWidth: 2, dash: [5])
)
.foregroundColor(borderColor)
)
)
.animation(.easeInOut(duration: 0.2), value: isDropTarget)
}
private var borderColor: Color {
guard isDropTarget, let valid = isValidDrop else {
return Color(hex: "#E0E0E0")
}
return valid ? .mealMoodSuccess : .mealMoodError
}
}
struct EatingOutSlotView: View {
let mealType: MealType
var body: some View {
VStack(spacing: 6) {
Image(systemName: "fork.knife.circle")
.font(.system(size: 20))
.foregroundColor(Color(hex: "#A0C4B8"))
Text("slot_eating_out")
.font(.mealMoodCaption)
.foregroundColor(Color(hex: "#6B9E90"))
}
.frame(maxWidth: .infinity, minHeight: 80)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(Color(hex: "#EEF8F5"))
.overlay(
RoundedRectangle(cornerRadius: 12)
.strokeBorder(
style: StrokeStyle(lineWidth: 2, dash: [5])
)
.foregroundColor(Color(hex: "#A0C4B8"))
)
)
}
}
/// "Not planning this meal" intentionally blank, resolved slot.
struct SkippedSlotView: View {
let mealType: MealType
var body: some View {
VStack(spacing: 6) {
Image(systemName: "minus.circle")
.font(.system(size: 20))
.foregroundColor(Color(hex: "#B9B4AE"))
Text("slot_skipped")
.font(.mealMoodCaption)
.foregroundColor(Color(hex: "#8E8B86"))
}
.frame(maxWidth: .infinity, minHeight: 80)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(Color(hex: "#F5F3F0"))
.overlay(
RoundedRectangle(cornerRadius: 12)
.strokeBorder(
style: StrokeStyle(lineWidth: 2, dash: [5])
)
.foregroundColor(Color(hex: "#CFCAC4"))
)
)
}
}