wip
This commit is contained in:
		@@ -11,12 +11,14 @@ enum WorkoutStatus: Int, Codable {
 | 
			
		||||
    case notStarted = 1
 | 
			
		||||
    case inProgress = 2
 | 
			
		||||
    case completed = 3
 | 
			
		||||
    case skipped = 4
 | 
			
		||||
    
 | 
			
		||||
    var checkboxStatus: CheckboxStatus {
 | 
			
		||||
        switch (self) {
 | 
			
		||||
        case .notStarted: .unchecked
 | 
			
		||||
        case .inProgress: .intermediate
 | 
			
		||||
        case .completed: .checked
 | 
			
		||||
        case .skipped: .cancelled
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										180
									
								
								Workouts/Resources/exercises.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								Workouts/Resources/exercises.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
			
		||||
- name: Lat Pull Down
 | 
			
		||||
  setup: 'Seat: 3, Thigh Pad: 4'
 | 
			
		||||
  descr: Sit upright with your knees secured under the pad. Grip the bar wider than
 | 
			
		||||
    shoulder-width. Pull the bar down to your chest, squeezing your shoulder blades
 | 
			
		||||
    together. Avoid leaning back excessively or using momentum.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 60
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Latissimus Dorsi
 | 
			
		||||
  - Trapezius
 | 
			
		||||
  - Rhomboids
 | 
			
		||||
  - Biceps Brachii
 | 
			
		||||
- name: Seated Row
 | 
			
		||||
  setup: 'Seat: 2, Chest Pad: 3'
 | 
			
		||||
  descr: With your chest firmly against the pad, grip the handles and pull straight
 | 
			
		||||
    back while keeping your elbows close to your body. Focus on retracting your shoulder
 | 
			
		||||
    blades and avoid rounding your back.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 60
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Latissimus Dorsi
 | 
			
		||||
  - Rhomboids
 | 
			
		||||
  - Trapezius
 | 
			
		||||
  - Biceps Brachii
 | 
			
		||||
- name: Shoulder Press
 | 
			
		||||
  setup: 'Seat: 4'
 | 
			
		||||
  descr: Sit with your back against the pad, grip the handles just outside shoulder-width.
 | 
			
		||||
    Press upward without locking out your elbows. Keep your neck relaxed and avoid
 | 
			
		||||
    shrugging your shoulders.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 30
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Deltoid (Anterior)
 | 
			
		||||
  - Deltoid (Lateral)
 | 
			
		||||
  - Triceps Brachii
 | 
			
		||||
- name: Chest Press
 | 
			
		||||
  setup: 'Seat: 3'
 | 
			
		||||
  descr: Adjust the seat so the handles are at mid-chest height. Push forward until
 | 
			
		||||
    arms are nearly extended, then return slowly. Keep wrists straight and don’t let
 | 
			
		||||
    your elbows drop too low.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 40
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Pectoralis Major
 | 
			
		||||
  - Triceps Brachii
 | 
			
		||||
  - Deltoid (Anterior)
 | 
			
		||||
- name: Tricep Press
 | 
			
		||||
  setup: 'Seat: 2'
 | 
			
		||||
  descr: With elbows close to your sides, press the handles downward in a controlled
 | 
			
		||||
    motion. Avoid flaring your elbows or using your shoulders to assist the motion.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 60
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Triceps Brachii
 | 
			
		||||
- name: Arm Curl
 | 
			
		||||
  setup: 'Seat: 3'
 | 
			
		||||
  descr: Position your arms over the pad and grip the handles. Curl the weight upward
 | 
			
		||||
    while keeping your upper arms stationary. Avoid using momentum and fully control
 | 
			
		||||
    the lowering phase.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 30
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Biceps Brachii
 | 
			
		||||
  - Brachialis
 | 
			
		||||
- name: Abdominal
 | 
			
		||||
  setup: 'Seat: 2, Back Pad: 3'
 | 
			
		||||
  descr: Sit with the pads resting against your chest. Contract your abs to curl forward,
 | 
			
		||||
    keeping your lower back in contact with the pad. Avoid pulling with your arms
 | 
			
		||||
    or hips.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 60
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Rectus Abdominis
 | 
			
		||||
  - Internal Obliques
 | 
			
		||||
- name: Rotary
 | 
			
		||||
  setup: 'Seat: 3, Start Angle: Centered'
 | 
			
		||||
  descr: Rotate your torso from side to side in a controlled motion, keeping your
 | 
			
		||||
    hips still. Focus on using your obliques to generate the twist, not momentum or
 | 
			
		||||
    the arms.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 60
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Internal Obliques
 | 
			
		||||
  - External Obliques
 | 
			
		||||
- name: Leg Press
 | 
			
		||||
  setup: 'Seat Angle: 4, Platform: Middle'
 | 
			
		||||
  descr: Place your feet shoulder-width on the platform. Press upward through your
 | 
			
		||||
    heels without locking your knees. Keep your back flat against the pad throughout
 | 
			
		||||
    the motion.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 130
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Gluteus Maximus
 | 
			
		||||
  - Rectus Femoris
 | 
			
		||||
  - Vastus Lateralis
 | 
			
		||||
  - Vastus Medialis
 | 
			
		||||
  - Vastus Intermedius
 | 
			
		||||
  - Biceps Femoris
 | 
			
		||||
  - Semitendinosus
 | 
			
		||||
  - Semimembranosus
 | 
			
		||||
- name: Leg Extension
 | 
			
		||||
  setup: 'Seat: 3, Pad: Above ankle'
 | 
			
		||||
  descr: Sit upright and align your knees with the pivot point. Extend your legs to
 | 
			
		||||
    a straightened position, then lower with control. Avoid jerky movements or lifting
 | 
			
		||||
    your hips off the seat.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 70
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Rectus Femoris
 | 
			
		||||
  - Vastus Lateralis
 | 
			
		||||
  - Vastus Medialis
 | 
			
		||||
  - Vastus Intermedius
 | 
			
		||||
- name: Leg Curl
 | 
			
		||||
  setup: 'Seat: 2, Pad: Above ankle'
 | 
			
		||||
  descr: Lie face down or sit depending on the version. Curl your legs toward your
 | 
			
		||||
    glutes, focusing on hamstring engagement. Avoid arching your back or using momentum.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 60
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Biceps Femoris
 | 
			
		||||
  - Semitendinosus
 | 
			
		||||
  - Semimembranosus
 | 
			
		||||
- name: Adductor
 | 
			
		||||
  setup: 'Seat: 3, Start Position: Wide'
 | 
			
		||||
  descr: Sit with legs placed outside the pads. Bring your legs together using inner
 | 
			
		||||
    thigh muscles. Control the motion both in and out, avoiding fast swings.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 110
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Adductor Longus
 | 
			
		||||
  - Adductor Brevis
 | 
			
		||||
  - Adductor Magnus
 | 
			
		||||
  - Gracilis
 | 
			
		||||
- name: Abductor
 | 
			
		||||
  setup: 'Seat: 3, Start Position: Narrow'
 | 
			
		||||
  descr: Sit with legs inside the pads and push outward to engage outer thighs and
 | 
			
		||||
    glutes. Avoid leaning forward and keep the motion controlled throughout.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 110
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Gluteus Medius
 | 
			
		||||
  - Tensor Fasciae Latae
 | 
			
		||||
- name: Calfs
 | 
			
		||||
  setup: 'Seat: 3, Toe Bar: Midfoot'
 | 
			
		||||
  descr: Place the balls of your feet on the platform with heels hanging off. Raise
 | 
			
		||||
    your heels by contracting your calves, then slowly lower them below the platform
 | 
			
		||||
    level for a full stretch.
 | 
			
		||||
  sets: 3
 | 
			
		||||
  reps: 10
 | 
			
		||||
  weight: 60
 | 
			
		||||
  type: Machine-Based
 | 
			
		||||
  muscles:
 | 
			
		||||
  - Gastrocnemius
 | 
			
		||||
  - Soleus
 | 
			
		||||
@@ -13,12 +13,14 @@ enum CheckboxStatus {
 | 
			
		||||
    case checked
 | 
			
		||||
    case unchecked
 | 
			
		||||
    case intermediate
 | 
			
		||||
    case cancelled
 | 
			
		||||
    
 | 
			
		||||
    var color: Color {
 | 
			
		||||
        switch (self) {
 | 
			
		||||
        case .checked: .green
 | 
			
		||||
        case .unchecked: .gray
 | 
			
		||||
        case .intermediate: .yellow
 | 
			
		||||
        case .cancelled: .red
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@@ -27,6 +29,7 @@ enum CheckboxStatus {
 | 
			
		||||
        case .checked: "checkmark.circle.fill"
 | 
			
		||||
        case .unchecked: "circle"
 | 
			
		||||
        case .intermediate: "ellipsis.circle"
 | 
			
		||||
        case .cancelled: "cross.circle"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								Workouts/Utils/Color+darker.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Workouts/Utils/Color+darker.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Color+darker.swift
 | 
			
		||||
// Workouts
 | 
			
		||||
//
 | 
			
		||||
// Created by rzen on 7/17/25 at 9:20 AM.
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import SwiftUI
 | 
			
		||||
import UIKit
 | 
			
		||||
 | 
			
		||||
extension Color {
 | 
			
		||||
    func darker(by percentage: CGFloat) -> Color {
 | 
			
		||||
        let uiColor = UIColor(self)
 | 
			
		||||
        var hue: CGFloat = 0
 | 
			
		||||
        var saturation: CGFloat = 0
 | 
			
		||||
        var brightness: CGFloat = 0
 | 
			
		||||
        var alpha: CGFloat = 0
 | 
			
		||||
 | 
			
		||||
        if uiColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) {
 | 
			
		||||
            let newBrightness = max(brightness * (1 - percentage), 0)
 | 
			
		||||
            let darkerUIColor = UIColor(hue: hue, saturation: saturation, brightness: newBrightness, alpha: alpha)
 | 
			
		||||
            return Color(darkerUIColor)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self // Fallback if color can't be converted
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -30,21 +30,37 @@ struct SplitPickerView: View {
 | 
			
		||||
                            dismiss()
 | 
			
		||||
                        }) {
 | 
			
		||||
                            VStack {
 | 
			
		||||
                                ZStack {
 | 
			
		||||
                                ZStack(alignment: .bottom) {
 | 
			
		||||
                                    // Golden ratio rectangle (1:1.618)
 | 
			
		||||
                                    RoundedRectangle(cornerRadius: 12)
 | 
			
		||||
                                        .fill(split.getColor())
 | 
			
		||||
                                        .aspectRatio(1, contentMode: .fit)
 | 
			
		||||
                                        .fill(
 | 
			
		||||
                                            LinearGradient(
 | 
			
		||||
                                                gradient: Gradient(colors: [split.getColor(), split.getColor().darker(by: 0.2)]),
 | 
			
		||||
                                                startPoint: .topLeading,
 | 
			
		||||
                                                endPoint: .bottomTrailing
 | 
			
		||||
                                            )
 | 
			
		||||
                                        )
 | 
			
		||||
                                        .aspectRatio(1.618, contentMode: .fit)
 | 
			
		||||
                                        .shadow(radius: 2)
 | 
			
		||||
                                    
 | 
			
		||||
                                    Image(systemName: split.systemImage)
 | 
			
		||||
                                        .font(.system(size: 30))
 | 
			
		||||
                                        .foregroundColor(.white)
 | 
			
		||||
                                    VStack {
 | 
			
		||||
                                        // Icon in the center
 | 
			
		||||
                                        Image(systemName: split.systemImage)
 | 
			
		||||
                                            .font(.system(size: 40, weight: .medium))
 | 
			
		||||
                                            .foregroundColor(.white)
 | 
			
		||||
                                            .offset(y: -15)
 | 
			
		||||
                                        
 | 
			
		||||
                                        // Name at the bottom inside the rectangle
 | 
			
		||||
                                        Text(split.name)
 | 
			
		||||
                                            .font(.headline)
 | 
			
		||||
                                            .foregroundColor(.white)
 | 
			
		||||
                                            .lineLimit(1)
 | 
			
		||||
                                            .padding(.horizontal, 8)
 | 
			
		||||
                                            .padding(.bottom, 8)
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                
 | 
			
		||||
                                Text(split.name)
 | 
			
		||||
                                    .font(.headline)
 | 
			
		||||
                                    .lineLimit(1)
 | 
			
		||||
                                
 | 
			
		||||
                                // Exercise count below the rectangle
 | 
			
		||||
                                Text("\(split.exercises?.count ?? 0) exercises")
 | 
			
		||||
                                    .font(.caption)
 | 
			
		||||
                                    .foregroundColor(.secondary)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,11 +40,12 @@ struct WorkoutsView: View {
 | 
			
		||||
                                )
 | 
			
		||||
                            }
 | 
			
		||||
                            .swipeActions(edge: .trailing, allowsFullSwipe: false) {
 | 
			
		||||
                                Button(role: .destructive) {
 | 
			
		||||
                                Button {
 | 
			
		||||
                                    itemToDelete = workout
 | 
			
		||||
                                } label: {
 | 
			
		||||
                                    Label("Delete", systemImage: "trash")
 | 
			
		||||
                                }
 | 
			
		||||
                                .tint(.red)
 | 
			
		||||
                                Button {
 | 
			
		||||
                                    itemToEdit = workout
 | 
			
		||||
                                } label: {
 | 
			
		||||
@@ -77,9 +78,11 @@ struct WorkoutsView: View {
 | 
			
		||||
            ) {
 | 
			
		||||
                Button("Delete", role: .destructive) {
 | 
			
		||||
                    if let item = itemToDelete {
 | 
			
		||||
                        modelContext.delete(item)
 | 
			
		||||
                        try? modelContext.save()
 | 
			
		||||
                        itemToDelete = nil
 | 
			
		||||
                        withAnimation {
 | 
			
		||||
                            modelContext.delete(item)
 | 
			
		||||
                            try? modelContext.save()
 | 
			
		||||
                            itemToDelete = nil
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Button("Cancel", role: .cancel) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user