import SwiftUI // MARK: - Home View struct HomeView: View { @EnvironmentObject var appState: AppState @State private var showPartnerHome = false @State private var showBucketList = false @State private var showCreateInvite = false @State private var showAcceptInvite = false var body: some View { ScrollView { VStack(spacing: CloserSpacing.xl) { // Welcome header VStack(alignment: .leading, spacing: 4) { Text("Welcome back") .font(CloserFont.callout) .foregroundColor(.closerTextSecondary) Text(appState.currentUser?.displayName ?? "Partner") .font(CloserFont.title1) .foregroundColor(.closerText) } .frame(maxWidth: .infinity, alignment: .leading) .closerPadding() if appState.currentCouple == nil { PartnerActivationCard( onInvite: { showCreateInvite = true }, onAcceptInvite: { showAcceptInvite = true } ) .closerPadding() } else { // Streak card StreakCard() .closerPadding() } // Quick actions VStack(alignment: .leading, spacing: CloserSpacing.md) { Text("Today") .closerSectionTitle() .closerPadding() ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: CloserSpacing.md) { QuickActionCard( icon: "heart.fill", title: "Daily Question", subtitle: "Connect with your partner", color: .closerPrimary ) QuickActionCard( icon: "gamecontroller.fill", title: "Play Together", subtitle: "Games & challenges", color: .closerSecondary ) QuickActionCard( icon: "sparkles", title: "Date Ideas", subtitle: "Plan something fun", color: .closerGold ) } .padding(.horizontal, CloserSpacing.xl) } } if appState.currentCouple != nil { // Partner status VStack(alignment: .leading, spacing: CloserSpacing.sm) { Text("Partner") .closerSectionTitle() .closerPadding() PartnerStatusRow( displayName: appState.currentPartner?.displayName ?? "Your Partner", answered: false, lastActive: nil ) .closerPadding() } // Relationship summary VStack(alignment: .leading, spacing: CloserSpacing.sm) { Text("Your Journey") .closerSectionTitle() .closerPadding() VStack(spacing: CloserSpacing.sm) { StatRow(icon: "flame.fill", label: "Streak", value: "\(appState.currentCouple?.streakCount ?? 0) days") StatRow(icon: "questionmark.bubble.fill", label: "Questions Answered", value: "12") StatRow(icon: "gamecontroller.fill", label: "Games Played", value: "5") } .closerPadding() } // Bottom nav to partner home Button(action: { showPartnerHome = true }) { Label("View Partner's Activity", systemImage: "person.fill") } .buttonStyle(SecondaryButtonStyle()) .closerPadding() } Spacer() .frame(height: CloserSpacing.xxl) } } .background(Color.closerBackground) .navigationBarTitleDisplayMode(.inline) .navigationDestination(isPresented: $showPartnerHome) { PartnerHomeView() } .navigationDestination(isPresented: $showBucketList) { BucketListView() } .navigationDestination(isPresented: $showCreateInvite) { CreateInviteView() } .navigationDestination(isPresented: $showAcceptInvite) { AcceptInviteView() } } } // MARK: - Partner Home struct PartnerHomeView: View { @Environment(\.dismiss) private var dismiss var body: some View { ScrollView { VStack(spacing: CloserSpacing.xl) { VStack(alignment: .leading, spacing: 4) { Text("Partner's Activity") .font(CloserFont.title1) .foregroundColor(.closerText) Text("See what your partner has been up to") .font(CloserFont.callout) .foregroundColor(.closerTextSecondary) } .frame(maxWidth: .infinity, alignment: .leading) .closerPadding() EmptyStateView( icon: "person.crop.circle.badge.questionmark", title: "No Recent Activity", message: "Activity updates will appear here when your partner answers questions or plays games." ) } } .background(Color.closerBackground) .navigationBarTitleDisplayMode(.inline) } } // MARK: - Subviews struct StreakCard: View { @EnvironmentObject var appState: AppState var body: some View { HStack { VStack(alignment: .leading, spacing: 4) { Text("Couple Streak") .font(CloserFont.subheadline) .foregroundColor(.closerTextSecondary) HStack(spacing: 8) { Image(systemName: "flame.fill") .foregroundColor(.closerDanger) Text("\(appState.currentCouple?.streakCount ?? 0) days") .font(CloserFont.title2) .foregroundColor(.closerText) } } Spacer() // Streak dots HStack(spacing: 6) { ForEach(0..<7) { i in Circle() .fill(i < (appState.currentCouple?.streakCount ?? 0) % 7 ? Color.closerDanger : Color.closerDivider) .frame(width: 12, height: 12) } } } .padding(CloserSpacing.lg) .closerCard() } } struct QuickActionCard: View { let icon: String let title: String let subtitle: String let color: Color var body: some View { VStack(alignment: .leading, spacing: CloserSpacing.sm) { Image(systemName: icon) .font(.title2) .foregroundColor(color) Text(title) .font(CloserFont.headline) .foregroundColor(.closerText) Text(subtitle) .font(CloserFont.caption) .foregroundColor(.closerTextSecondary) } .padding(CloserSpacing.lg) .frame(width: 160, alignment: .leading) .closerCard() } } struct StatRow: View { let icon: String let label: String let value: String var body: some View { HStack { Image(systemName: icon) .foregroundColor(.closerPrimary) .frame(width: 24) Text(label) .font(CloserFont.callout) .foregroundColor(.closerText) Spacer() Text(value) .font(CloserFont.headline) .foregroundColor(.closerText) } .padding(CloserSpacing.md) .background(Color.closerSurface) .cornerRadius(CloserRadius.medium) } }