import SwiftUI struct Habit: Identifiable { let id = Int.random(in: 0...99999) let name: String let icon: String var streak: Int var done: Bool } struct HabitRingView: View { @State private var habits: [Habit] = [ Habit(name: "Morning stretch", icon: "figure.cooldown", streak: 14, done: true), Habit(name: "Read 20 pages", icon: "book", streak: 9, done: false), Habit(name: "Deep work block", icon: "target", streak: 21, done: false), Habit(name: "Walk outside", icon: "figure.walk", streak: 5, done: false), Habit(name: "No screens after 10", icon: "moon", streak: 3, done: false) ] private var completed: Int { habits.filter(\.done).count } private var progress: Double { habits.isEmpty ? 0 : Double(completed) / Double(habits.count) } var body: some View { ZStack { Color(red: 0.04, green: 0.04, blue: 0.06).ignoresSafeArea() ScrollView { VStack(alignment: .leading, spacing: 16) { Text("TUESDAY, 14 MAY") .font(.caption).bold().foregroundColor(Color(red: 0.49, green: 0.36, blue: 1)) Text("Today").font(.system(size: 34, weight: .heavy)).foregroundColor(.white) ZStack { Circle().stroke(Color.white.opacity(0.08), lineWidth: 9).frame(width: 150, height: 150) Circle() .trim(from: 0, to: progress) .stroke(Color(red: 0.49, green: 0.36, blue: 1), style: StrokeStyle(lineWidth: 9, lineCap: .round)) .rotationEffect(.degrees(-90)) .frame(width: 150, height: 150) .animation(.easeInOut, value: progress) VStack { Text("\(Int(progress * 100))%").font(.system(size: 36, weight: .heavy)).foregroundColor(.white) Text("\(completed) of \(habits.count)").font(.footnote).foregroundColor(.gray) } } .frame(maxWidth: .infinity) .padding(.vertical, 20) ForEach($habits) { $habit in Button { habit.done.toggle() habit.streak += habit.done ? 1 : -1 } label: { HStack(spacing: 14) { Image(systemName: habit.icon) .font(.title3).frame(width: 46, height: 46) .background(Color.white.opacity(0.06)).cornerRadius(13) .foregroundColor(.white) VStack(alignment: .leading, spacing: 3) { Text(habit.name).fontWeight(.semibold) .strikethrough(habit.done) .foregroundColor(habit.done ? .gray : .white) Text("🔥 \(habit.streak) days").font(.footnote).foregroundColor(.gray) } Spacer() Image(systemName: habit.done ? "checkmark.circle.fill" : "circle") .foregroundColor(habit.done ? Color(red: 0.49, green: 0.36, blue: 1) : .gray) .font(.title2) } .padding(14) .background(Color.white.opacity(0.04)).cornerRadius(18) } } } .padding(22) } } } } #Preview { HabitRingView() }