import SwiftUI struct HabitsView: View { @EnvironmentObject var authManager: AuthManager @State private var habits: [Habit] = [] @State private var isLoading = true var completedCount: Int { habits.filter { $0.completedToday == true }.count } var body: some View { ZStack { Color(hex: "0a0a1a").ignoresSafeArea() VStack(spacing: 0) { HStack { VStack(alignment: .leading) { Text("Привычки").font(.title.bold()).foregroundColor(.white) Text("\(completedCount)/\(habits.count) выполнено").font(.subheadline).foregroundColor(Color(hex: "8888aa")) } Spacer() }.padding() // Progress bar if !habits.isEmpty { GeometryReader { geo in ZStack(alignment: .leading) { RoundedRectangle(cornerRadius: 4).fill(Color.white.opacity(0.1)) RoundedRectangle(cornerRadius: 4).fill(Color(hex: "00d4aa")) .frame(width: geo.size.width * CGFloat(completedCount) / CGFloat(max(habits.count, 1))) } } .frame(height: 6) .padding(.horizontal) .padding(.bottom, 16) } if isLoading { ProgressView().tint(Color(hex: "00d4aa")).padding(.top, 40) Spacer() } else if habits.isEmpty { VStack(spacing: 12) { Text("🔥").font(.system(size: 50)) Text("Нет привычек").foregroundColor(Color(hex: "8888aa")) }.padding(.top, 60) Spacer() } else { List { ForEach(habits) { habit in HabitRowView(habit: habit) { await logHabit(habit) } .listRowBackground(Color.clear) .listRowSeparator(.hidden) } } .listStyle(.plain) .scrollContentBackground(.hidden) } } } .task { await loadHabits() } .refreshable { await loadHabits() } } func loadHabits() async { isLoading = true habits = (try? await APIService.shared.getHabits(token: authManager.token)) ?? [] isLoading = false } func logHabit(_ habit: Habit) async { try? await APIService.shared.logHabit(token: authManager.token, id: habit.id) await loadHabits() UIImpactFeedbackGenerator(style: .medium).impactOccurred() } }