import sqlite3 import models import ui def manage_workout_templates(conn: sqlite3.Connection) -> None: while True: ui.clear_screen() ui.print_header("Manage Workout Templates") print("1. List Templates") print("2. Create Template") print("3. View/Edit Template") print("4. Delete Template") print("5. Back") choice = input("\n> ").strip() if choice == "1": list_workout_templates(conn) elif choice == "2": create_workout_template(conn) elif choice == "3": edit_workout_template(conn) elif choice == "4": delete_workout_template(conn) elif choice == "5": break def list_workout_templates(conn: sqlite3.Connection, pause: bool = True) -> None: templates = models.list_workout_templates(conn) ui.print_header("All Workout Templates") ui.print_table( ["ID", "Name", "Exercises"], [[str(t["id"]), t["name"], t["exercises"] or ""] for t in templates], ) if pause: ui.pause() def create_workout_template(conn: sqlite3.Connection) -> None: name = ui.prompt_str("Template name: ") assert name is not None try: template_id = models.create_workout_template(conn, name) print(f'Template "{name}" created.') except sqlite3.IntegrityError: print(f'Template "{name}" already exists.') ui.pause() return # Immediately enter exercise editor print("Now add exercises to the template.") ui.pause() edit_template_exercises(conn, template_id) def edit_workout_template(conn: sqlite3.Connection) -> None: templates = models.list_workout_templates(conn) if not templates: print("\nNo templates defined.") return list_workout_templates(conn, pause=False) tid = ui.prompt_int("\nTemplate ID to edit: ") assert tid is not None template = models.get_workout_template(conn, tid) if not template: print("Template not found.") return edit_template_exercises(conn, tid) def edit_template_exercises(conn: sqlite3.Connection, template_id: int) -> None: """Interactive editor for a template's exercise list.""" while True: ui.clear_screen() template, entries = models.get_workout_template_detail(conn, template_id) assert template is not None ui.print_header(f'Template: {template["name"]}') # Build in-memory list from current DB state exercises_data: list[dict] = [ { "exercise_id": e["exercise_id"], "exercise_name": e["exercise_name"], "bw_relative": bool(e["bw_relative"]), "sets": e["sets"], "reps": e["reps"], "lsrpe": e["lsrpe"], "rest_time": e["rest_time"], "note": e["note"], } for e in entries ] if exercises_data: ui.print_table( ["#", "Exercise", "Sets", "Reps", "LSRPE", "Rest", "Note"], [ [ str(i), e["exercise_name"], str(e["sets"]), str(e["reps"]), str(e["lsrpe"]), f"{e['rest_time']}s", e["note"] or "", ] for i, e in enumerate(exercises_data, 1) ], ) else: print(" (no exercises)") print( "\nActions: (a)dd exercise, (r)emove, (m)ove, (e)dit defaults, (n)ame, (b)ack" ) action = input("> ").strip().lower() if action == "b": break elif action == "n": new_name = ui.prompt_str("New template name: ") assert new_name is not None try: models.update_workout_template_name(conn, template_id, new_name) print(f'Template renamed to "{new_name}".') except sqlite3.IntegrityError: print(f'Template "{new_name}" already exists.') ui.pause() elif action == "a": available = models.list_workout_exercises(conn) if not available: print("No exercises defined. Create some first.") continue print("\nAvailable exercises:") for e in available: print(f" {e['id']}. {e['name']}") eid = ui.prompt_int("\nExercise ID to add: ") assert eid is not None ex = models.get_workout_exercise(conn, eid) if not ex: print("Exercise not found.") continue print(f"\n -- {ex['name']} (defaults) --") sets = ui.prompt_int(" Sets: ", min_val=1) reps = ui.prompt_int(" Reps: ", min_val=1) lsrpe = ui.prompt_int(" LSRPE: ", min_val=1, max_val=10) rest_time = ui.prompt_int(" Rest time in seconds: ", min_val=0) note = ui.prompt_str(" Note (optional): ", required=False) exercises_data.append( { "exercise_id": eid, "sets": sets, "reps": reps, "lsrpe": lsrpe, "rest_time": rest_time, "note": note, } ) models.save_workout_template_exercises(conn, template_id, exercises_data) print(f'"{ex["name"]}" added to template.') ui.pause() elif action == "r": if not exercises_data: print("No exercises to remove.") continue pos = ui.prompt_int("Position # to remove: ", min_val=1) assert pos is not None if pos > len(exercises_data): print("Invalid position.") continue removed = exercises_data.pop(pos - 1) models.save_workout_template_exercises(conn, template_id, exercises_data) print(f'Removed "{removed["exercise_name"]}".') ui.pause() elif action == "m": if len(exercises_data) < 2: print("Need at least 2 exercises to move.") continue from_pos = ui.prompt_int( "Move from position #: ", min_val=1, max_val=len(exercises_data) ) to_pos = ui.prompt_int( "Move to position #: ", min_val=1, max_val=len(exercises_data) ) assert from_pos is not None and to_pos is not None item = exercises_data.pop(from_pos - 1) exercises_data.insert(to_pos - 1, item) models.save_workout_template_exercises(conn, template_id, exercises_data) print("Exercise moved.") ui.pause() elif action == "e": if not exercises_data: print("No exercises to edit.") continue pos = ui.prompt_int("Position # to edit: ", min_val=1) assert pos is not None if pos > len(exercises_data): print("Invalid position.") continue entry = exercises_data[pos - 1] print(f'\n -- {entry["exercise_name"]} (edit defaults) --') entry["sets"] = ui.prompt_int( f" Sets [{entry['sets'] or ''}]: ", min_val=1, default=entry["sets"] ) entry["reps"] = ui.prompt_int( f" Reps [{entry['reps'] or ''}]: ", min_val=1, default=entry["reps"] ) entry["lsrpe"] = ui.prompt_int( f" LSRPE [{entry['lsrpe']}]: ", min_val=1, max_val=10, default=entry["lsrpe"], ) entry["rest_time"] = ui.prompt_int( f" Rest time in seconds [{entry['rest_time']}]: ", min_val=0, default=entry["rest_time"], ) entry["note"] = ui.prompt_str( f" Note [{entry['note'] or ''}]: ", required=False, default=entry["note"], ) models.save_workout_template_exercises(conn, template_id, exercises_data) print("Defaults updated.") ui.pause() def delete_workout_template(conn: sqlite3.Connection) -> None: templates = models.list_workout_templates(conn) if not templates: print("\nNo templates defined.") return list_workout_templates(conn, pause=False) tid = ui.prompt_int("\nTemplate ID to delete: ") assert tid is not None template = models.get_workout_template(conn, tid) if not template: print("Template not found.") return if not ui.confirm(f'Delete template "{template["name"]}"?'): return models.delete_workout_template(conn, tid) print("Template deleted.") ui.pause()