From b9d80fb6b6448615355f6d1385364460498cda4e Mon Sep 17 00:00:00 2001 From: Yusuf Suleman Date: Fri, 3 Apr 2026 09:18:21 -0500 Subject: [PATCH] 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) --- ios/Platform/Platform/ContentView.swift | 64 ++++++++++++++----- .../Assistant/AssistantChatView.swift | 21 ++++++ 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/ios/Platform/Platform/ContentView.swift b/ios/Platform/Platform/ContentView.swift index 0c0308b..a92a126 100644 --- a/ios/Platform/Platform/ContentView.swift +++ b/ios/Platform/Platform/ContentView.swift @@ -63,28 +63,62 @@ struct MainTabView: View { } struct AssistantSheetView: View { + @Environment(\.dismiss) private var dismiss @State private var selectedMode = 0 var body: some View { - NavigationStack { - VStack(spacing: 0) { - Picker("Mode", selection: $selectedMode) { - Text("AI Chat").tag(0) - Text("Quick Add").tag(1) - } - .pickerStyle(.segmented) - .padding(.horizontal) - .padding(.top, 8) + VStack(spacing: 0) { + // Custom header — warm background + VStack(spacing: 12) { + // Drag handle + Capsule() + .fill(Color.textTertiary.opacity(0.3)) + .frame(width: 36, height: 5) + .padding(.top, 8) - if selectedMode == 0 { - AssistantChatView() - } else { - FoodSearchView(isSheet: true) + 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 { + AssistantChatView() + } else { + FoodSearchView(isSheet: true) } - .navigationTitle("Add Food") - .navigationBarTitleDisplayMode(.inline) } + .background(Color.canvas) .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()) + } + } } diff --git a/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift b/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift index e9051f9..4212643 100644 --- a/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift +++ b/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift @@ -10,6 +10,27 @@ struct AssistantChatView: View { ScrollViewReader { proxy in ScrollView { 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 chatBubble(message) .id(message.id)