import SwiftUI import WatchKit /// Routine quotidienne sur la montre : liste des blocs, cochables au doigt. /// Chaque coche part vers l'iPhone, qui la POSTe au serveur — l'état est donc /// partagé avec la page /routine et le widget de la home. struct RoutineView: View { @StateObject private var store = RoutineStore.shared @Environment(\.dismiss) private var dismiss var body: some View { Group { if store.isEmpty { emptyState } else { list } } .navigationTitle("Routine") } private var emptyState: some View { VStack(spacing: 8) { Image(systemName: "figure.cooldown") .font(.title2) .foregroundStyle(.secondary) Text("Ouvre l'app Coach sur l'iPhone une fois pour recevoir la routine.") .font(.footnote) .multilineTextAlignment(.center) .foregroundStyle(.secondary) } .padding() } private var list: some View { ScrollView { VStack(spacing: 6) { progressHeader if !store.morningBlocks.isEmpty { sectionTitle("Le matin") ForEach(store.morningBlocks) { block in row(block) } } if !store.otherBlocks.isEmpty { sectionTitle("Après la course") ForEach(store.otherBlocks) { block in row(block) } } if store.lastSyncFailed { Button { store.retry() } label: { Label("Renvoyer vers l'iPhone", systemImage: "arrow.clockwise") .font(.footnote) } .tint(.orange) .padding(.top, 4) } } .padding(.horizontal, 4) } } private var progressHeader: some View { let total = store.blocks.count let count = store.done.count return VStack(spacing: 4) { Text("\(count) / \(total) blocs") .font(.headline) .foregroundStyle(count == total && total > 0 ? .green : .primary) ProgressView(value: total > 0 ? Double(count) / Double(total) : 0) .tint(.cyan) } .padding(.vertical, 4) } private func sectionTitle(_ text: String) -> some View { Text(text.uppercased()) .font(.caption2) .foregroundStyle(.secondary) .frame(maxWidth: .infinity, alignment: .leading) .padding(.top, 6) } private func row(_ block: RoutineBlock) -> some View { let isDone = store.done.contains(block.id) return Button { store.toggle(block.id) WKInterfaceDevice.current().play(isDone ? .click : .success) } label: { HStack(spacing: 8) { Image(systemName: isDone ? "checkmark.circle.fill" : "circle") .foregroundStyle(isDone ? .green : .secondary) VStack(alignment: .leading, spacing: 1) { Text(block.title) .font(.footnote) .multilineTextAlignment(.leading) .strikethrough(isDone, color: .secondary) Text("\(block.durationMin) min") .font(.caption2) .foregroundStyle(.secondary) } Spacer(minLength: 0) } .frame(maxWidth: .infinity, alignment: .leading) } .buttonStyle(.plain) .padding(.vertical, 6) .padding(.horizontal, 8) .background(Color.gray.opacity(isDone ? 0.10 : 0.18), in: RoundedRectangle(cornerRadius: 8)) .opacity(isDone ? 0.65 : 1) } }