fix: warm sheet header, welcome state for AI chat, consistent colors
- Custom sheet header with warm canvas background (no white bar) - Tab picker styled as warm pills (not default segmented control) - AI Chat welcome state: sparkles icon + 'What did you eat?' prompt - All backgrounds use canvas color consistently Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -63,28 +63,62 @@ struct MainTabView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct AssistantSheetView: View {
|
struct AssistantSheetView: View {
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
@State private var selectedMode = 0
|
@State private var selectedMode = 0
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
Picker("Mode", selection: $selectedMode) {
|
// Custom header — warm background
|
||||||
Text("AI Chat").tag(0)
|
VStack(spacing: 12) {
|
||||||
Text("Quick Add").tag(1)
|
// Drag handle
|
||||||
}
|
Capsule()
|
||||||
.pickerStyle(.segmented)
|
.fill(Color.textTertiary.opacity(0.3))
|
||||||
.padding(.horizontal)
|
.frame(width: 36, height: 5)
|
||||||
.padding(.top, 8)
|
.padding(.top, 8)
|
||||||
|
|
||||||
|
Text("Add Food")
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundStyle(Color.textPrimary)
|
||||||
|
|
||||||
|
// Tab picker — warm styled
|
||||||
|
HStack(spacing: 4) {
|
||||||
|
tabButton("AI Chat", icon: "sparkles", index: 0)
|
||||||
|
tabButton("Quick Add", icon: "magnifyingglass", index: 1)
|
||||||
|
}
|
||||||
|
.padding(4)
|
||||||
|
.background(Color.textTertiary.opacity(0.08))
|
||||||
|
.clipShape(Capsule())
|
||||||
|
.padding(.horizontal, 40)
|
||||||
|
}
|
||||||
|
.padding(.bottom, 12)
|
||||||
|
.background(Color.canvas)
|
||||||
|
|
||||||
|
// Content
|
||||||
if selectedMode == 0 {
|
if selectedMode == 0 {
|
||||||
AssistantChatView()
|
AssistantChatView()
|
||||||
} else {
|
} else {
|
||||||
FoodSearchView(isSheet: true)
|
FoodSearchView(isSheet: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle("Add Food")
|
.background(Color.canvas)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
|
||||||
}
|
|
||||||
.presentationDetents([.large])
|
.presentationDetents([.large])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func tabButton(_ title: String, icon: String, index: Int) -> some View {
|
||||||
|
Button {
|
||||||
|
withAnimation(.easeInOut(duration: 0.2)) { selectedMode = index }
|
||||||
|
} label: {
|
||||||
|
HStack(spacing: 5) {
|
||||||
|
Image(systemName: icon)
|
||||||
|
.font(.caption2)
|
||||||
|
Text(title)
|
||||||
|
.font(.subheadline.weight(selectedMode == index ? .semibold : .regular))
|
||||||
|
}
|
||||||
|
.foregroundStyle(selectedMode == index ? Color.textPrimary : Color.textTertiary)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.background(selectedMode == index ? Color.surfaceCard : Color.clear)
|
||||||
|
.clipShape(Capsule())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,27 @@ struct AssistantChatView: View {
|
|||||||
ScrollViewReader { proxy in
|
ScrollViewReader { proxy in
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVStack(spacing: 8) {
|
LazyVStack(spacing: 8) {
|
||||||
|
// Welcome state when no messages
|
||||||
|
if vm.messages.isEmpty {
|
||||||
|
VStack(spacing: 16) {
|
||||||
|
Spacer(minLength: 60)
|
||||||
|
Image(systemName: "sparkles")
|
||||||
|
.font(.system(size: 40))
|
||||||
|
.foregroundStyle(Color.accentWarm.opacity(0.4))
|
||||||
|
Text("What did you eat?")
|
||||||
|
.font(.title3.weight(.semibold))
|
||||||
|
.foregroundStyle(Color.textPrimary)
|
||||||
|
Text("Describe your food naturally.\n\"2 eggs and toast for breakfast\"\nor snap a photo of your meal.")
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundStyle(Color.textSecondary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.lineSpacing(4)
|
||||||
|
Spacer(minLength: 60)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.horizontal, 32)
|
||||||
|
}
|
||||||
|
|
||||||
ForEach(vm.messages) { message in
|
ForEach(vm.messages) { message in
|
||||||
chatBubble(message)
|
chatBubble(message)
|
||||||
.id(message.id)
|
.id(message.id)
|
||||||
|
|||||||
Reference in New Issue
Block a user