- SwiftUI + async/await architecture - Barcode scanning with AVFoundation - Product display with score ring, NOVA badge, nutrition - Alternatives with sort/filter - Auth (login/register) - Favorites & history - Account management - Dark theme - Connected to food.payfrit.com API (Open Food Facts proxy) Co-Authored-By: Claude <noreply@anthropic.com>
76 lines
2.4 KiB
Swift
76 lines
2.4 KiB
Swift
import SwiftUI
|
|
|
|
struct DietaryPills: View {
|
|
let tags: [String]
|
|
|
|
var body: some View {
|
|
ScrollView(.horizontal, showsIndicators: false) {
|
|
HStack(spacing: 8) {
|
|
ForEach(tags, id: \.self) { tag in
|
|
DietaryPill(tag: tag)
|
|
}
|
|
}
|
|
.padding(.horizontal)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct DietaryPill: View {
|
|
let tag: String
|
|
|
|
var body: some View {
|
|
HStack(spacing: 4) {
|
|
Image(systemName: iconName)
|
|
.font(.caption)
|
|
Text(displayName)
|
|
.font(.caption.bold())
|
|
}
|
|
.foregroundColor(pillColor)
|
|
.padding(.horizontal, 12)
|
|
.padding(.vertical, 6)
|
|
.background(pillColor.opacity(0.15))
|
|
.cornerRadius(20)
|
|
}
|
|
|
|
private var displayName: String {
|
|
switch tag.lowercased() {
|
|
case "vegan": return "Vegan"
|
|
case "vegetarian": return "Vegetarian"
|
|
case "gluten-free", "glutenfree", "gf": return "Gluten-Free"
|
|
case "dairy-free", "dairyfree", "df": return "Dairy-Free"
|
|
case "nut-free", "nutfree", "nf": return "Nut-Free"
|
|
case "organic": return "Organic"
|
|
case "non-gmo", "nongmo": return "Non-GMO"
|
|
case "keto": return "Keto"
|
|
case "paleo": return "Paleo"
|
|
default: return tag.capitalized
|
|
}
|
|
}
|
|
|
|
private var iconName: String {
|
|
switch tag.lowercased() {
|
|
case "vegan": return "leaf.fill"
|
|
case "vegetarian": return "carrot.fill"
|
|
case "gluten-free", "glutenfree", "gf": return "wheat"
|
|
case "dairy-free", "dairyfree", "df": return "drop.fill"
|
|
case "nut-free", "nutfree", "nf": return "xmark.circle.fill"
|
|
case "organic": return "leaf.arrow.circlepath"
|
|
case "non-gmo", "nongmo": return "checkmark.seal.fill"
|
|
case "keto": return "flame.fill"
|
|
case "paleo": return "fossil.shell.fill"
|
|
default: return "tag.fill"
|
|
}
|
|
}
|
|
|
|
private var pillColor: Color {
|
|
switch tag.lowercased() {
|
|
case "vegan", "vegetarian", "organic": return .green
|
|
case "gluten-free", "glutenfree", "gf": return .orange
|
|
case "dairy-free", "dairyfree", "df": return .blue
|
|
case "nut-free", "nutfree", "nf": return .red
|
|
case "non-gmo", "nongmo": return .purple
|
|
case "keto", "paleo": return .pink
|
|
default: return .gray
|
|
}
|
|
}
|
|
}
|