diff --git a/tabatago-swift/TabataGo/Models/MockPrograms.swift b/tabatago-swift/TabataGo/Models/MockPrograms.swift new file mode 100644 index 0000000..f9a976e --- /dev/null +++ b/tabatago-swift/TabataGo/Models/MockPrograms.swift @@ -0,0 +1,727 @@ +import Foundation + +struct MockPrograms { + static let all: [WorkoutProgram] = _build() +} + +extension MockPrograms { + private static func _build() -> [WorkoutProgram] { + let block = TabataBlockBuilder() + return [ + // ─── Upper Body Free ──────────────────────────────── + _program("681616f7-97b8-4998-8f56-b327e3aa552d", + "Épaules & Bras Doux", "Gentle Shoulders & Arms", + "Programme débutant pour renforcer doucement les épaules et les bras.", + "upper-body", "Beginner", "#4A90D9", 90, + blocks: [ + block(1, + ex1("Cercles bras tendus", "Arm circles", + "Gardez les bras à hauteur d'épaules, petits puis grands cercles", + "Keep arms at shoulder height, small then large circles", + "Cercles plus petits", "Smaller circles", + "Cercles plus grands et plus rapides", "Larger and faster circles"), + ex2("Élévations latérales", "Lateral raises", + "Montez lentement les bras sur le côté, paumes vers le bas", + "Raise arms slowly to the sides, palms facing down", + "Sans charge, amplitude réduite", "No weight, reduced range", + "Avec bouteilles d'eau", "With water bottles")), + block(2, + ex1("Flexions au mur", "Wall push-ups", + "Mains écartées largeur épaules, descendez lentement", + "Hands shoulder-width apart, lower slowly", + "Plus près du mur", "Closer to the wall", + "Push-ups au sol sur les genoux", "Knee push-ups on floor"), + ex2("Press épaules sans charge", "Shoulder press no weight", + "Poussez au-dessus de la tête, coudes à 90° au départ", + "Push overhead, elbows at 90° to start", + "Amplitude réduite", "Reduced range", + "Avec légères charges", "With light weights")), + block(3, + ex1("Shrugs épaules", "Shoulder shrugs", + "Montez les épaules vers les oreilles, maintenez 2 secondes", + "Shrug shoulders toward ears, hold 2 seconds", + "Sans maintien", "No hold", + "Avec charge", "With weight"), + ex2("Rotation poignets", "Wrist circles", + "Rotations lentes dans les deux sens pour préparer les avant-bras", + "Slow rotations both directions to prepare forearms", + "Amplitude réduite", "Reduced range", + "Avec poings serrés", "With clenched fists")), + ]), + _program("11168ec3-531d-4097-9b90-fb41689a9b63", + "Dos & Biceps Initiation", "Back & Biceps Initiation", + "Initiation au renforcement du dos et des biceps avec des mouvements simples et accessibles.", + "upper-body", "Beginner", "#4A90D9", 85, + blocks: [ + block(1, + ex1("Tirage élastique assis", "Seated band row", + "Tirez les coudes en arrière, serrez les omoplates", + "Pull elbows back, squeeze shoulder blades", + "Élastique léger, amplitude réduite", "Light band, reduced range", + "Élastique plus tendu", "Tighter band"), + ex2("Curl biceps debout", "Standing bicep curls", + "Coudes collés au corps, montez et descendez lentement", + "Elbows pinned to body, curl up and down slowly", + "Sans charge, amplitude partielle", "No weight, partial range", + "Avec bouteilles d'eau", "With water bottles")), + block(2, + ex1("Superman au sol", "Superman hold", + "Levez bras et jambes simultanément, maintenez 3 secondes", + "Lift arms and legs together, hold 3 seconds", + "Bras seuls ou jambes seules", "Arms only or legs only", + "Superman alterné", "Alternating superman"), + ex2("Tirage menton imaginaire", "Upright row mime", + "Tirez les coudes vers le haut le long du corps", + "Pull elbows up along the body", + "Sans charge, mouvement lent", "No weight, slow movement", + "Avec légère charge", "With light weight")), + block(3, + ex1("Rétraction omoplates", "Scapular retraction", + "Serrez les omoplates ensemble, maintenez 3 secondes", + "Squeeze shoulder blades together, hold 3 seconds", + "Assis, sans résistance", "Seated, no resistance", + "Avec élastique", "With band"), + ex2("Flexion poignets", "Wrist curls", + "Fléchissez les poignets vers le haut, avant-bras sur les cuisses", + "Flex wrists upward, forearms on thighs", + "Sans charge", "No weight", + "Avec légère charge", "With light weight")), + ]), + _program("87d53233-3fa7-4fa7-bba3-e5ab1a5d5931", + "Haut du Corps Tonus", "Upper Body Tone", + "Programme intermédiaire pour tonifier l'ensemble du haut du corps. Alternance push/pull.", + "upper-body", "Intermediate", "#4A90D9", 120, + blocks: [ + block(1, + ex1("Push-ups classiques", "Standard push-ups", + "Corps gainé, descendez jusqu'au sol, remontez en poussant fort", + "Plank body, lower to floor, push up strong", + "Sur les genoux", "On knees", + "Pieds surélevés", "Feet elevated"), + ex2("Dips sur chaise", "Chair dips", + "Mains sur le bord d'une chaise, descendez les coudes à 90°", + "Hands on chair edge, lower elbows to 90°", + "Pieds plus près, amplitude réduite", "Feet closer, reduced range", + "Pieds surélevés", "Feet elevated")), + block(2, + ex1("Pompes diamant", "Diamond push-ups", + "Mains rapprochées sous la poitrine, pouces et index forment un diamant", + "Hands close under chest, thumbs and index form a diamond", + "Écartement plus large", "Wider hand position", + "Avec pause en bas", "With bottom pause"), + ex2("Pike push-ups", "Pike push-ups", + "Hanches hautes, descendez le front vers le sol", + "Hips high, lower forehead toward floor", + "Amplitude réduite", "Reduced range", + "Pieds surélevés", "Feet elevated")), + block(3, + ex1("Burpees sans saut", "Burpee no jump", + "Descendez au sol, remontez en position debout, pas de saut", + "Lower to floor, stand back up, no jump", + "Sans push-up au sol", "No push-up on floor", + "Burpees complets avec saut", "Full burpees with jump"), + ex2("Mountain climbers", "Mountain climbers", + "Ramenez alternativement les genoux vers la poitrine en position de planche", + "Alternate driving knees to chest in plank position", + "Plus lent", "Slower", + "Plus rapide", "Faster")), + ]), + _program("9fd7f33c-2502-4f8f-be27-c15907daded0", + "Upper Body Burn", "Upper Body Burn", + "Programme avancé haute intensité. Push-ups, dips, et mouvements explosifs.", + "upper-body", "Advanced", "#4A90D9", 160, + blocks: [ + block(1, + ex1("Push-ups clap", "Clap push-ups", + "Explosez vers le haut, tapez les mains avant de replonger", + "Explode upward, clap hands before landing", + "Push-ups rapides sans clap", "Fast push-ups no clap", + "Avec poids lesté", "With weighted vest"), + ex2("Explosive dips", "Explosive dips", + "Poussez fort pour décoller les mains de la chaise", + "Push hard to lift hands off chair", + "Dips contrôlés", "Controlled dips", + "Avec poids sur les cuisses", "With weight on lap")), + block(2, + ex1("Archer push-ups", "Archer push-ups", + "Un bras tendu sur le côté, l'autre fléchit pour la pompe", + "One arm extended to side, other bends for push-up", + "Écartement réduit", "Reduced spread", + "Pompe à un bras complète", "Full one-arm push-up"), + ex2("Pike push-ups explosifs", "Explosive pike push-ups", + "Poussez explosivement hors du sol en position pike", + "Push explosively off floor in pike position", + "Pike push-ups contrôlés", "Controlled pike push-ups", + "Handstand push-ups contre mur", "Wall handstand push-ups")), + block(3, + ex1("Burpees complets", "Full burpees", + "Saut explosif en haut, va-et-vient complet au sol", + "Explosive jump at top, full down-and-up", + "Sans saut ni push-up", "No jump or push-up", + "Burpee pull-ups si barre disponible", "Burpee pull-ups if bar available"), + ex2("Spiderman push-ups", "Spiderman push-ups", + "Ramenez le genou vers le coude pendant la descente, alternez", + "Drive knee to elbow on the way down, alternate", + "Push-ups classiques", "Standard push-ups", + "Avec résistance élastique", "With band resistance")), + ]), + // ─── Lower Body Free ──────────────────────────────── + _program("22d65930-a9ff-49b2-a8f4-8c4c7068a8cf", + "Jambes Légères", "Light Legs", + "Programme débutant pour activer les jambes en douceur.", + "lower-body", "Beginner", "#9B59B6", 95, + blocks: [ + block(1, + ex1("Squats au mur", "Wall sit squats", + "Dos contre le mur, descendez à 90°, maintenez", + "Back against wall, lower to 90°, hold", + "Squats libres sans mur", "Free squats without wall", + "Wall sit statique 20s", "Static wall sit 20s"), + ex2("Marche sur place montées genoux", "High knee marches", + "Lever les genoux haut, alternance droite-gauche", + "Lift knees high, alternate right-left", + "Plus lent, genoux moins hauts", "Slower, lower knees", + "Plus rapide avec saut léger", "Faster with light bounce")), + block(2, + ex1("Fentes stationnaires", "Stationary lunges", + "Un pas en avant, descendez le genou arrière, remontez", + "Step forward, lower back knee, stand up", + "Amplitude réduite", "Reduced range", + "Fentes marchées", "Walking lunges"), + ex2("Calf raises", "Calf raises", + "Montez sur la pointe des pieds, redescendez lentement", + "Rise onto toes, lower slowly", + "Les deux pieds, amplitude réduite", "Both feet, reduced range", + "Un pied à la fois", "One foot at a time")), + block(3, + ex1("Glute bridge", "Glute bridges", + "Allongé, pieds au sol, montez les hanches en serrant les fessiers", + "Lying down, feet on floor, raise hips squeezing glutes", + "Amplitude réduite", "Reduced range", + "Single leg bridge", "Bridge sur une jambe"), + ex2("Clamshell", "Clamshells", + "Sur le côté, genoux fléchis, ouvrez le genou du haut", + "On side, knees bent, open top knee", + "Amplitude réduite", "Reduced range", + "Avec élastique", "With band")), + ]), + _program("6eb4bfc2-0f6e-4784-a6d1-3a812341c434", + "Fessiers & Cuisses Doux", "Gentle Glutes & Thighs", + "Renforcement doux des fessiers et cuisses.", + "lower-body", "Beginner", "#9B59B6", 90, + blocks: [ + block(1, + ex1("Squats sumo", "Sumo squats", + "Pieds écartés, pointes vers l'extérieur, descendez lentement", + "Feet wide, toes out, lower slowly", + "Amplitude réduite", "Reduced range", + "Avec poids au sol entre les pieds", "With weight between feet"), + ex2("Donkey kicks", "Donkey kicks", + "À quatre pattes, poussez un pied vers le plafond", + "On all fours, push one foot toward ceiling", + "Amplitude réduite, plus lent", "Reduced range, slower", + "Avec élastique", "With band")), + block(2, + ex1("Step-ups sur marche", "Step-ups on step", + "Montez sur une marche, jambe tendue en haut, redescendez", + "Step up onto a step, leg straight at top, step down", + "Marche plus basse", "Lower step", + "Marche plus haute", "Higher step"), + ex2("Fire hydrants", "Fire hydrants", + "À quatre pattes, levez le genou sur le côté comme un chien", + "On all fours, lift knee to side like a dog", + "Plus lent", "Slower", + "Avec élastique", "With band")), + block(3, + ex1("Squat plié lent", "Slow plié squats", + "Position ballet, descendez très lentement sur 3 secondes", + "Ballet position, lower very slowly over 3 seconds", + "Pas de pause en bas", "No pause at bottom", + "Avec pulsations en bas", "With pulses at bottom"), + ex2("Leg raises latéral", "Side leg raises", + "Allongé sur le côté, levez la jambe du haut lentement", + "Lying on side, lift top leg slowly", + "Amplitude réduite", "Reduced range", + "Avec élastique cheville", "With ankle band")), + ]), + _program("78840358-2118-4e63-942b-f6ffa7799c8d", + "Lower Body Power", "Lower Body Power", + "Programme intermédiaire pour des jambes fortes.", + "lower-body", "Intermediate", "#9B59B6", 130, + blocks: [ + block(1, + ex1("Squats sautés", "Jump squats", + "Descendez en squat, explosez vers le haut, atterrissez en douceur", + "Lower into squat, explode upward, land softly", + "Squats rapides sans saut", "Fast squats no jump", + "Squats sautés avec torsion", "Jump squats with twist"), + ex2("Fentes sautées", "Jumping lunges", + "Alternez les jambes en sautant, genou avant à 90°", + "Alternate legs jumping, front knee at 90°", + "Fentes alternées rapides sans saut", "Fast alternating lunges no jump", + "Fentes sautées avec poids", "Jumping lunges with weight")), + block(2, + ex1("Bulgarian split squat", "Bulgarian split squats", + "Pied arrière surélevé, descendez le genou arrière vers le sol", + "Rear foot elevated, lower back knee toward floor", + "Sans élévation", "No elevation", + "Avec poids dans chaque main", "With weights in each hand"), + ex2("Romanian deadlift mime", "Romanian deadlift mime", + "Hanches poussées en arrière, dos droit, descendez jusqu'à tension ischios", + "Hips pushed back, straight back, lower until hamstring tension", + "Amplitude réduite", "Reduced range", + "Avec poids", "With weight")), + block(3, + ex1("Skater jumps", "Skater jumps", + "Saut latéral d'un pied à l'autre, atterrissez sur une jambe", + "Lateral jump foot to foot, land on one leg", + "Pas latéraux sans saut", "Lateral steps no jump", + "Plus amples et plus rapides", "Wider and faster"), + ex2("Squat pulse", "Squat pulses", + "Restez en bas du squat, petites pulsations de haut en bas", + "Stay at bottom of squat, small up-down pulses", + "Demi-amplitude", "Half range", + "Pulsations plus profondes", "Deeper pulses")), + ]), + _program("2439ee21-a73e-4f35-ac28-5dfeeb1249ab", + "Leg Destroyer", "Leg Destroyer", + "Programme avancé. Jump squats, pistol squats assistés et plyométrie pure.", + "lower-body", "Advanced", "#9B59B6", 170, + blocks: [ + block(1, + ex1("Pistol squat assisté", "Assisted pistol squats", + "Une jambe tendue devant, descendez sur l'autre en tenant un support", + "One leg extended front, lower on other holding support", + "Avec chaise pour soutien", "With chair for support", + "Pistol squat complet", "Full pistol squat"), + ex2("Box jumps", "Box jumps", + "Saut explosif sur une surface surélevée, atterrissez en squat", + "Explosive jump onto elevated surface, land in squat", + "Step-ups rapides", "Fast step-ups", + "Box jumps plus hautes", "Higher box jumps")), + block(2, + ex1("Jump squat deep", "Deep jump squats", + "Squat très profond, saut maximal, atterrissage contrôlé", + "Very deep squat, max jump, controlled landing", + "Squat profond sans saut", "Deep squat no jump", + "Avec lest", "With weight vest"), + ex2("Single leg deadlift", "Single leg deadlifts", + "Équilibre sur une jambe, penchez-vous en avant, jambe arrière tendue", + "Balance on one leg, hinge forward, back leg straight", + "Avec support", "With support", + "Avec poids", "With weight")), + block(3, + ex1("Tuck jumps", "Tuck jumps", + "Saut vertical, ramenez les genoux à la poitrine en l'air", + "Vertical jump, tuck knees to chest in air", + "Squats sautés normaux", "Regular jump squats", + "Tuck jumps consécutifs sans pause", "Continuous tuck jumps"), + ex2("Explosive lunges", "Explosive lunges", + "Fentes avec saut et changement de jambe explosif à chaque rep", + "Lunges with explosive leg switch jump each rep", + "Fentes marchées rapides", "Fast walking lunges", + "Fentes sautées avec haltères", "Jump lunges with dumbbells")), + ]), + // ─── Full Body Free ───────────────────────────────── + _program("3a62af9d-af30-4afd-9144-295bde20a28d", + "Full Body Éveil", "Full Body Awakening", + "Programme débutant complet pour réveiller tout le corps.", + "full-body", "Beginner", "#00C896", 100, + blocks: [ + block(1, + ex1("Jumping jacks doux", "Gentle jumping jacks", + "Bras vers le haut, pieds écartés, mouvement fluide", + "Arms up, feet apart, fluid motion", + "Step touches sans saut", "Step touches no jump", + "Plus rapides", "Faster"), + ex2("Squats légers", "Bodyweight squats", + "Pieds largeur épaules, descendez comme pour s'asseoir", + "Feet shoulder-width, lower as if sitting", + "Demi-squats", "Half squats", + "Squats complets avec pause en bas", "Full squats with bottom pause")), + block(2, + ex1("Marche en montagne lente", "Slow mountain climbers", + "Position planche, ramenez un genou puis l'autre lentement", + "Plank position, bring one knee then other slowly", + "Plus lent", "Slower", + "Plus rapide", "Faster"), + ex2("Push-ups au mur", "Wall push-ups", + "Mains sur le mur, descendez et poussez, corps gainé", + "Hands on wall, lower and push, body tight", + "Plus près du mur", "Closer to wall", + "Push-ups au sol sur genoux", "Floor knee push-ups")), + block(3, + ex1("Glute bridge", "Glute bridges", + "Au sol, pieds plans, montez les hanches en serrant les fessiers", + "On floor, flat feet, raise hips squeezing glutes", + "Amplitude réduite", "Reduced range", + "Single leg bridge", "One-leg bridge"), + ex2("Planche genoux", "Knee plank", + "Avant-bras au sol, genoux au sol, corps aligné", + "Forearms down, knees down, body aligned", + "Sur les mains au lieu des avant-bras", "On hands instead of forearms", + "Planche complète sur pieds", "Full plank on feet")), + ]), + _program("76609f2f-ea94-4138-9d43-9b46f3406404", + "Cardio & Renforcement Doux", "Gentle Cardio & Strength", + "Alternance cardio léger et renforcement pour un premier pas accessible.", + "full-body", "Beginner", "#00C896", 95, + blocks: [ + block(1, + ex1("Pas chassés latéraux", "Lateral shuffles", + "Déplacez-vous latéralement en restant bas, changez de direction", + "Move laterally staying low, change direction", + "Plus lent", "Slower", + "Plus rapide avec touche au sol", "Faster with floor touch"), + ex2("Curl biceps sans charge", "Bicep curls no weight", + "Coudes collés, montez et descendez les avant-bras", + "Elbows pinned, raise and lower forearms", + "Amplitude partielle", "Partial range", + "Avec bouteilles d'eau", "With water bottles")), + block(2, + ex1("Squat + punch", "Squat punches", + "Descendez en squat, en remontant lancez deux punches alternés", + "Lower into squat, throw two alternate punches on way up", + "Squat sans punch", "Squat no punch", + "Plus rapide avec jump", "Faster with jump"), + ex2("Superman", "Superman", + "Au sol ventre en bas, levez bras et jambes ensemble", + "On floor face down, lift arms and legs together", + "Bras seuls", "Arms only", + "Avec rotation", "With rotation")), + block(3, + ex1("Step-ups alternés", "Alternate step-ups", + "Montez sur une marche en alternant les jambes", + "Step up on a step alternating legs", + "Marche plus basse", "Lower step", + "Marche plus haute", "Higher step"), + ex2("Bird dog", "Bird dogs", + "À quatre pattes, tendez bras opposé et jambe opposée", + "On all fours, extend opposite arm and leg", + "Sans équilibre prolongé", "Without hold", + "Avec pause 3 secondes", "With 3-second hold")), + ]), + _program("39e380ea-619f-4695-b00b-4e727f752d2e", + "Full Body HIIT", "Full Body HIIT", + "Programme intermédiaire haute intensité.", + "full-body", "Intermediate", "#00C896", 140, + blocks: [ + block(1, + ex1("Burpees sans saut", "Burpee no jump", + "Au sol et debout, pas de saut en haut, rythme soutenu", + "Floor to standing, no top jump, steady pace", + "Sans push-up", "No push-up", + "Burpees complets avec saut", "Full burpees with jump"), + ex2("Mountain climbers rapides", "Fast mountain climbers", + "Planche haute, genoux rapides vers la poitrine", + "High plank, fast knees to chest", + "Plus lent", "Slower", + "Cross-body mountain climbers", "Cross-body climbers")), + block(2, + ex1("Push-ups + row", "Push-up to renegade row", + "Une pompe puis tirez un coude en arrière, alternez", + "One push-up then pull one elbow back, alternate", + "Push-ups + tirage sans poids", "Push-ups + no-weight row", + "Avec haltères", "With dumbbells"), + ex2("Jump squats", "Jump squats", + "Squat profond, saut vertical, atterrissage souple", + "Deep squat, vertical jump, soft landing", + "Squats rapides sans saut", "Fast squats no jump", + "Tuck squats (genoux à la poitrine)", "Tuck squats (knees to chest)")), + block(3, + ex1("Plank jack", "Plank jacks", + "Position planche, sautez pieds écartés puis serrés", + "Plank position, jump feet apart then together", + "Step au lieu de sauter", "Step instead of jump", + "Plus rapide", "Faster"), + ex2("Renegade row mime", "Renegade row mime", + "Position planche haute, tirez un coude en arrière, alternez", + "High plank, pull one elbow back, alternate", + "Sans poids, plus lent", "No weight, slower", + "Avec haltères ou bouteilles", "With dumbbells or bottles")), + ]), + _program("c0d7962e-973a-405c-97d5-c77843841beb", + "Total Annihilation", "Total Annihilation", + "Programme avancé. Burpees, plyométrie et mouvements composés.", + "full-body", "Advanced", "#00C896", 180, + blocks: [ + block(1, + ex1("Burpees complets", "Full burpees", + "Saut en haut, push-up au sol, va-et-vient explosif complet", + "Top jump, floor push-up, full explosive cycle", + "Burpees sans push-up", "Burpees no push-up", + "Burpee pull-ups", "Burpee pull-ups"), + ex2("Man-makers", "Man-makers", + "Push-up + row each arm + squat + press overhead", + "Push-up + row each arm + squat + press overhead", + "Sans poids, amplitude réduite", "No weight, reduced range", + "Avec haltères", "With dumbbells")), + block(2, + ex1("Pop squats", "Pop squats", + "Saut latéral d'un côté à l'autre en squat à chaque atterrissage", + "Lateral jump side to side in squat on each landing", + "Squats latéraux sans saut", "Lateral squats no jump", + "Plus amples et plus rapides", "Wider and faster"), + ex2("Spider push-ups", "Spiderman push-ups", + "Pompe + ramenez genou au coude du même côté à chaque descente", + "Push-up + drive knee to same-side elbow each descent", + "Push-ups classiques", "Standard push-ups", + "Avec résistance", "With resistance")), + block(3, + ex1("Squat thrust + tuck", "Squat thrust to tuck jump", + "Descendez au sol en squat thrust, remontez en tuck jump", + "Down to squat thrust, up to tuck jump", + "Sans tuck jump", "No tuck jump", + "Avec push-up au sol", "With floor push-up"), + ex2("Ice skater explosif", "Explosive skaters", + "Saut latéral d'un pied à l'autre amplitude maximale", + "Lateral jump foot to foot at max range", + "Skaters modérés", "Moderate skaters", + "Avec pause sur une jambe", "With single-leg hold")), + ]), + // ─── Premium ───────────────────────────────────────── + _program("f0ba130e-9a16-469b-a6ab-463ae7c47a10", + "Bras & Épaules Sculpté", "Sculpted Arms & Shoulders", + "Programme intermédiaire ciblé bras et épaules.", + "upper-body", "Intermediate", "#4A90D9", 125, isFree: false, + blocks: [ + block(1, + ex1p("Push-ups surélevés", "Decline push-ups", + "Pieds sur chaise, mains au sol, descendez lentement", + "Feet on chair, hands on floor, lower slowly"), + ex2p("Dips profonds", "Deep dips", + "Amplitude maximale, pause en bas", + "Full range, pause at bottom")), + block(2, + ex1p("Curl + press", "Curl to press", + "Curl biceps puis poussez au-dessus de la tête", + "Bicep curl then press overhead"), + ex2p("Push-ups diamant", "Diamond push-ups", + "Mains serrées, triceps isolés", + "Hands close, triceps isolated")), + block(3, + ex1p("L-fly latéral", "Lateral raises", + "Bras tendus sur les côtés, montez à hauteur épaules", + "Straight arms to sides, raise to shoulder height"), + ex2p("Shrugs + rotation", "Shrug rotations", + "Montez épaules puis rotation vers l'avant", + "Shrug up then rotate forward")), + ]), + _program("1f31f624-351a-430e-a7d4-45ab3ed44765", + "Cuisses & Mollets Force", "Power Thighs & Calves", + "Programme intermédiaire pour des cuisses puissantes.", + "lower-body", "Intermediate", "#9B59B6", 135, isFree: false, + blocks: [ + block(1, + ex1p("Front squats", "Front squats", + "Mains croisées, coudes hauts, descendez profond", + "Arms crossed, elbows high, lower deep"), + ex2p("Calf raises unilatéral", "Single-leg calf raises", + "Sur un pied, montez sur la pointe", + "On one foot, rise onto toes")), + block(2, + ex1p("Walking lunges", "Walking lunges", + "Grands pas en avant, genou arrière frôle le sol", + "Long steps forward, back knee grazes floor"), + ex2p("Wall sit + jump", "Wall sit to jump", + "Wall sit 20s puis saut vertical", + "Wall sit 20s then vertical jump")), + block(3, + ex1p("Reverse lunges", "Reverse lunges", + "Pas en arrière, genou avant reste à 90°", + "Step backward, front knee stays at 90°"), + ex2p("Squat + calf raise", "Squat to calf raise", + "Remontez du squat sur la pointe des pieds", + "Rise from squat onto toes")), + ]), + _program("43541fed-0b1a-4d5f-8f65-779ddd82fd18", + "Métabolique Total", "Total Metabolic", + "Programme intermédiaire métabolique. Brûle maximum de calories.", + "full-body", "Intermediate", "#00C896", 150, isFree: false, + blocks: [ + block(1, + ex1p("Squat thrust rapide", "Fast squat thrusts", + "Descendez au sol et remontez le plus vite possible", + "Down to floor and back up as fast as possible"), + ex2p("Mountain climbers croisés", "Cross mountain climbers", + "Genou vers coude opposé, alternez vite", + "Knee to opposite elbow, alternate fast")), + block(2, + ex1p("Burpee + tuck", "Burpee to tuck jump", + "Burpee complet puis tuck jump vertical", + "Full burpee then vertical tuck jump"), + ex2p("Plank up-downs", "Plank up-downs", + "Planche haute vers basse et inversement, alternez les bras", + "High to low plank and back, alternate arms")), + block(3, + ex1p("High knees explosifs", "Explosive high knees", + "Montées de genoux rapides et hautes, bras en opposition", + "Fast high knee drives, arms in opposition"), + ex2p("Squat jumps rotations", "Squat jump twists", + "Saut en squat avec rotation 90° à chaque saut", + "Squat jump with 90° twist each jump")), + ]), + _program("51d071a7-c371-4fd1-966c-31d360a96421", + "Arms of Steel", "Arms of Steel", + "Programme avancé dédié aux bras.", + "upper-body", "Advanced", "#4A90D9", 165, isFree: false, + blocks: [ + block(1, + ex1p("Tricep dips explosifs", "Explosive tricep dips", + "Poussez fort pour décoller, atterrissez et replongez", + "Push hard to lift off, land and dive back"), + ex2p("Close-grip push-ups", "Close-grip push-ups", + "Mains serrées, coudes collés au corps", + "Hands close, elbows pinned to body")), + block(2, + ex1p("Curl 21s style", "21s style curls", + "7 basses + 7 hautes + 7 complètes, sans pause", + "7 bottom + 7 top + 7 full, no rest"), + ex2p("Pike push-ups", "Pike push-ups", + "Épaules au-dessus des mains, descendez le front", + "Shoulders over hands, lower forehead")), + block(3, + ex1p("Commando plank", "Commando plank", + "Montez de planche basse à haute et redescendez, alternez", + "Go from low to high plank and back, alternate"), + ex2p("Push-up clap", "Clap push-ups", + "Explosez pour taper les mains en l'air", + "Explode to clap hands in air")), + ]), + _program("3db31a8c-4047-47a1-a163-6ffa8449e25e", + "Plyo Legs Extreme", "Plyo Legs Extreme", + "Plyométrie pure pour les jambes.", + "lower-body", "Advanced", "#9B59B6", 175, isFree: false, + blocks: [ + block(1, + ex1p("Box jumps continus", "Continuous box jumps", + "Saut sur box, redescente souple, enchaînez sans pause", + "Jump onto box, soft landing, chain without rest"), + ex2p("Depth jumps", "Depth jumps", + "Descendez de la box, touchez le sol et sautez vertical", + "Step off box, touch floor and jump vertical")), + block(2, + ex1p("Bounds géants", "Bounding leaps", + "Sauts en longueur maximale d'un pied à l'autre", + "Max distance leaps foot to foot"), + ex2p("Single-leg hops", "Single-leg hops", + "Sauts sur place sur un pied, hauteur maximale", + "In-place hops on one foot, max height")), + block(3, + ex1p("Lateral box jumps", "Lateral box jumps", + "Face au côté de la box, saut latéral par-dessus", + "Facing side of box, lateral jump over"), + ex2p("Squat jumps profond", "Deep squat jumps", + "Squat très profond, saut le plus haut possible", + "Very deep squat, highest possible jump")), + ]), + _program("565b713a-4a65-4866-8584-044260010514", + "Warrior Workout", "Warrior Workout", + "Le défi ultime. Mouvements composés avancés, zéro repos mental.", + "full-body", "Advanced", "#00C896", 190, isFree: false, + blocks: [ + block(1, + ex1p("Burpee pull-up mime", "Burpee to pull-up mime", + "Burpee complet puis saut mains au-dessus comme un pull-up", + "Full burpee then jump hands up like a pull-up"), + ex2p("Turkish get-up mime", "Turkish get-up mime", + "Au sol à debout en passant par chaque étape", + "Floor to standing through each stage")), + block(2, + ex1p("Bear crawl", "Bear crawl", + "Quatre pattes, genoux décollés, avancez en opposition", + "On all fours, knees off ground, move in opposition"), + ex2p("Crab walk", "Crab walk", + "Assis face au plafond, avancez sur mains et pieds", + "Sitting face up, move on hands and feet")), + block(3, + ex1p("Burpee broad jump", "Burpee broad jumps", + "Burpee puis saut en longueur maximum en avant", + "Burpee then max forward broad jump"), + ex2p("Sprint sur place", "Sprint in place", + "Sprint maximal sur place, genoux très hauts", + "Max sprint in place, knees very high")), + ]), + ] + } + + // ─── Helpers ───────────────────────────────────────────────── + + private static func _program( + _ id: String, _ title: String, _ titleEn: String, _ desc: String, + _ zone: String, _ level: String, _ color: String, _ cals: Int, + isFree: Bool = true, + blocks: [TabataBlock] + ) -> WorkoutProgram { + let totalRounds = blocks.reduce(0) { $0 + $1.rounds } + let workSeconds = blocks.reduce(0) { $0 + $1.rounds * ($1.workTime + $1.restTime) } + return WorkoutProgram( + id: id, + title: title, + titleEn: titleEn, + description: desc, + descriptionEn: desc, + bodyZone: zone, + level: level, + musicVibe: "electronic", + accentColor: color, + isFree: isFree, + estimatedCalories: cals, + estimatedDuration: workSeconds / 60, + totalRounds: totalRounds, + warmup: WarmupSection(movements: [], totalDuration: 0), + cooldown: CooldownSection(movements: [], totalDuration: 0), + blocks: blocks, + thumbnailUrl: nil + ) + } +} + +// ─── Block builder (reduces repetition) ────────────────────────── + +private struct TabataBlockBuilder { + func callAsFunction( + _ position: Int, + _ ex1: TabataExercise, + _ ex2: TabataExercise, + rounds: Int = 8, work: Int = 20, rest: Int = 10 + ) -> TabataBlock { + TabataBlock( + id: UUID().uuidString, + position: position, + exercise1: ex1, + exercise2: ex2, + rounds: rounds, + workTime: work, + restTime: rest + ) + } +} + +// ─── Exercise builders ─────────────────────────────────────────── + +private func ex1(_ name: String, _ nameEn: String, + _ tip: String, _ tipEn: String, + _ mod: String, _ modEn: String, + _ prog: String, _ progEn: String) -> TabataExercise { + TabataExercise(name: name, nameEn: nameEn, tip: tip, tipEn: tipEn, + modification: mod, modificationEn: modEn, + progression: prog, progressionEn: progEn) +} + +private func ex2(_ name: String, _ nameEn: String, + _ tip: String, _ tipEn: String, + _ mod: String, _ modEn: String, + _ prog: String, _ progEn: String) -> TabataExercise { + TabataExercise(name: name, nameEn: nameEn, tip: tip, tipEn: tipEn, + modification: mod, modificationEn: modEn, + progression: prog, progressionEn: progEn) +} + +private func ex1p(_ name: String, _ nameEn: String, _ tip: String, _ tipEn: String) -> TabataExercise { + TabataExercise(name: name, nameEn: nameEn, tip: tip, tipEn: tipEn) +} + +private func ex2p(_ name: String, _ nameEn: String, _ tip: String, _ tipEn: String) -> TabataExercise { + TabataExercise(name: name, nameEn: nameEn, tip: tip, tipEn: tipEn) +} diff --git a/tabatago-swift/TabataGo/ViewModels/HomeViewModel.swift b/tabatago-swift/TabataGo/ViewModels/HomeViewModel.swift index ed95a3a..d36c559 100644 --- a/tabatago-swift/TabataGo/ViewModels/HomeViewModel.swift +++ b/tabatago-swift/TabataGo/ViewModels/HomeViewModel.swift @@ -52,9 +52,12 @@ final class HomeViewModel: ObservableObject { do { if let remote = try await SupabaseService.shared.fetchAllPrograms() { allPrograms = remote + } else { + allPrograms = MockPrograms.all } } catch { self.error = error.localizedDescription + allPrograms = MockPrograms.all } } }