Version casi lista
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
import SwiftUI
|
||||
|
||||
struct DishDrawerView: View {
|
||||
let dishes: [Dish]
|
||||
let tags: [Tag]
|
||||
let language: AppLanguage
|
||||
let usedDishIds: Set<UUID>
|
||||
var onAddDish: () -> Void
|
||||
var onQuickAssignDish: (Dish) -> Void
|
||||
var onEditDish: (Dish) -> Void
|
||||
var onDeleteDish: (Dish) -> Void
|
||||
@Binding var draggedDish: Dish?
|
||||
@State private var searchText: String = ""
|
||||
@State private var hideUsedThisWeek: Bool = false
|
||||
|
||||
private var filteredDishes: [Dish] {
|
||||
let term = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return dishes.filter { dish in
|
||||
let matchesSearch = term.isEmpty || dish.name.localizedCaseInsensitiveContains(term)
|
||||
let matchesUsedFilter = !hideUsedThisWeek || !usedDishIds.contains(dish.id)
|
||||
return matchesSearch && matchesUsedFilter
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 12) {
|
||||
HStack {
|
||||
HStack(spacing: 6) {
|
||||
Image(systemName: "list.clipboard")
|
||||
Text("home_my_dishes")
|
||||
.font(.mealMoodH3)
|
||||
}
|
||||
.foregroundColor(.mealMoodTextPrimary)
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(action: onAddDish) {
|
||||
Image(systemName: "plus.circle.fill")
|
||||
.font(.system(size: 28))
|
||||
.foregroundColor(.mealMoodCoral)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
|
||||
if dishes.isEmpty {
|
||||
VStack(spacing: 16) {
|
||||
Image(systemName: "fork.knife")
|
||||
.font(.system(size: 40))
|
||||
.foregroundColor(Color(hex: "#C4C4C4"))
|
||||
|
||||
Text("home_add_first_dish")
|
||||
.font(.mealMoodBody)
|
||||
.foregroundColor(.mealMoodTextSecondary)
|
||||
|
||||
PrimaryButton(title: String(localized: "home_add_dish"), icon: nil, action: onAddDish)
|
||||
.padding(.horizontal, 40)
|
||||
}
|
||||
.padding(.vertical, 32)
|
||||
} else {
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: "magnifyingglass")
|
||||
.foregroundColor(.mealMoodTextSecondary)
|
||||
TextField("home_my_dishes_search", text: $searchText)
|
||||
.font(.mealMoodBody)
|
||||
if !searchText.isEmpty {
|
||||
Button {
|
||||
searchText = ""
|
||||
} label: {
|
||||
Image(systemName: "xmark.circle.fill")
|
||||
.foregroundColor(.mealMoodTextSecondary)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 10)
|
||||
.background(Color.mealMoodSurface)
|
||||
.cornerRadius(12)
|
||||
.padding(.horizontal, 16)
|
||||
|
||||
Button {
|
||||
hideUsedThisWeek.toggle()
|
||||
} label: {
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: hideUsedThisWeek ? "checkmark.square.fill" : "square")
|
||||
.foregroundColor(hideUsedThisWeek ? .mealMoodCoral : .mealMoodTextSecondary)
|
||||
Text("home_my_dishes_hide_used")
|
||||
.font(.mealMoodSmall)
|
||||
.foregroundColor(.mealMoodTextPrimary)
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical, 6)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
LazyVStack(spacing: 8) {
|
||||
ForEach(filteredDishes) { dish in
|
||||
DishCardView(
|
||||
dish: dish,
|
||||
tags: tags,
|
||||
language: language,
|
||||
onEdit: { onEditDish(dish) },
|
||||
onDelete: { onDeleteDish(dish) }
|
||||
)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
onQuickAssignDish(dish)
|
||||
}
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: false) {
|
||||
Button {
|
||||
onEditDish(dish)
|
||||
} label: {
|
||||
Label("dish_edit_title", systemImage: "pencil")
|
||||
}
|
||||
.tint(.mealMoodCoral)
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
Button(role: .destructive) {
|
||||
onDeleteDish(dish)
|
||||
} label: {
|
||||
Label("dish_delete", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
.draggable("dish:\(dish.id.uuidString)") {
|
||||
DishCardView(dish: dish, tags: tags, language: language)
|
||||
.frame(width: 200)
|
||||
.opacity(0.8)
|
||||
}
|
||||
}
|
||||
|
||||
if filteredDishes.isEmpty {
|
||||
Text("home_my_dishes_search_empty")
|
||||
.font(.mealMoodBody)
|
||||
.foregroundColor(.mealMoodTextSecondary)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
}
|
||||
.padding(.top, 16)
|
||||
}
|
||||
}
|
||||
|
||||
struct DishCardView: View {
|
||||
let dish: Dish
|
||||
let tags: [Tag]
|
||||
let language: AppLanguage
|
||||
var onEdit: (() -> Void)? = nil
|
||||
var onDelete: (() -> Void)? = nil
|
||||
|
||||
private var dishTags: [Tag] {
|
||||
tags.filter { dish.tagIds.contains($0.id) }
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(dish.name)
|
||||
.font(.mealMoodBodyBold)
|
||||
.foregroundColor(.mealMoodTextPrimary)
|
||||
|
||||
if let desc = dish.descriptionText, !desc.isEmpty {
|
||||
Text(desc)
|
||||
.font(.mealMoodCaption)
|
||||
.foregroundColor(.mealMoodTextSecondary)
|
||||
.lineLimit(1)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack(spacing: 4) {
|
||||
ForEach(dishTags.prefix(3)) { tag in
|
||||
TagDot(color: tag.color, size: 10)
|
||||
}
|
||||
}
|
||||
|
||||
if onEdit != nil || onDelete != nil {
|
||||
HStack(spacing: 8) {
|
||||
if let onEdit {
|
||||
Button(action: onEdit) {
|
||||
Image(systemName: "pencil.circle")
|
||||
.foregroundColor(.mealMoodCoral)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
if let onDelete {
|
||||
Button(action: onDelete) {
|
||||
Image(systemName: "trash.circle")
|
||||
.foregroundColor(.mealMoodError)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(14)
|
||||
.mealCardStyle()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user