@page "/routines" @page "/{UserId}/routines" @inject ApiClient Api @inject NavigationManager Navigation @inject UserContext UserContext Routines
@if (ActiveRun is null) { @if (ExerciseList.Count == 0) {

No exercises yet

Add exercises first, then create routines.

} @if (ShowCreateRoutine) {

Create Routine

@foreach (var exercise in ExerciseList) { }
}

Your Routines

@if (IsLoading) {

Loading...

} else if (RoutineList.Count == 0) {

No routines yet. Create one above.

} else {
@foreach (var routine in RoutineList) {
@routine.Name
@string.Join(" ยท ", routine.Exercises.Select(e => e.Name))
}
}
@if (EditingRoutine is not null) {

Edit Routine

@foreach (var exercise in ExerciseList) { }
} } else {

Routine Run: @ActiveRun.Name

@foreach (var entry in RunEntries) {
kg
}
}
@code { [Parameter] public string? UserId { get; set; } private List ExerciseList { get; set; } = new(); private List RoutineList { get; set; } = new(); private bool IsLoading { get; set; } = true; private bool ShowCreateRoutine { get; set; } private string NewRoutineName { get; set; } = string.Empty; private HashSet SelectedExerciseIds { get; set; } = new(); private RoutineDto? EditingRoutine { get; set; } private string EditingName { get; set; } = string.Empty; private HashSet EditingExerciseIds { get; set; } = new(); private RoutineDto? ActiveRun { get; set; } private List RunEntries { get; set; } = new(); protected override async Task OnInitializedAsync() { var ensured = await Api.EnsureUserAsync(UserId); if (string.IsNullOrWhiteSpace(ensured)) { return; } UserContext.SetUserId(ensured); if (UserId != ensured) { Navigation.NavigateTo($"/{ensured}/routines", true); return; } await LoadDataAsync(); } private async Task LoadDataAsync() { IsLoading = true; ExerciseList = await Api.GetExercisesAsync(UserContext.UserId); RoutineList = await Api.GetRoutinesAsync(UserContext.UserId); IsLoading = false; } private void ToggleExercise(int exerciseId) { if (!SelectedExerciseIds.Add(exerciseId)) { SelectedExerciseIds.Remove(exerciseId); } } private async Task CreateRoutineAsync() { if (string.IsNullOrWhiteSpace(NewRoutineName)) { return; } var request = new RoutineUpsertRequest(NewRoutineName, SelectedExerciseIds.ToList()); var created = await Api.CreateRoutineAsync(UserContext.UserId, request); if (created is not null) { RoutineList.Add(created); RoutineList = RoutineList.OrderBy(r => r.Name).ToList(); NewRoutineName = string.Empty; SelectedExerciseIds.Clear(); } } private void ToggleCreate() { ShowCreateRoutine = !ShowCreateRoutine; } private void GoToExercises() { Navigation.NavigateTo($"/{UserContext.UserId}/exercises"); } private void StartEdit(RoutineDto routine) { EditingRoutine = routine; EditingName = routine.Name; EditingExerciseIds = routine.Exercises.Select(e => e.ExerciseId).ToHashSet(); } private void CancelEdit() { EditingRoutine = null; EditingName = string.Empty; EditingExerciseIds.Clear(); } private void ToggleEditExercise(int exerciseId) { if (!EditingExerciseIds.Add(exerciseId)) { EditingExerciseIds.Remove(exerciseId); } } private async Task SaveEditAsync() { if (EditingRoutine is null) { return; } var request = new RoutineUpsertRequest(EditingName, EditingExerciseIds.ToList()); var updated = await Api.UpdateRoutineAsync(UserContext.UserId, EditingRoutine.Id, request); if (updated is not null) { var index = RoutineList.FindIndex(r => r.Id == EditingRoutine.Id); if (index >= 0) { RoutineList[index] = updated; RoutineList = RoutineList.OrderBy(r => r.Name).ToList(); } } CancelEdit(); } private async Task StartRun(RoutineDto routine) { ActiveRun = routine; var lastRun = await Api.GetLastRunAsync(UserContext.UserId, routine.Id); RunEntries = routine.Exercises .OrderBy(e => e.Order) .Select(e => { var last = lastRun.Entries.FirstOrDefault(x => x.ExerciseId == e.ExerciseId); return new RoutineRunEntryDto(e.ExerciseId, last?.Weight ?? 0, false); }).ToList(); } private void ToggleRunCompleted(int exerciseId) { var entry = RunEntries.FirstOrDefault(e => e.ExerciseId == exerciseId); if (entry is null) { return; } entry.Completed = !entry.Completed; } private string GetExerciseName(int exerciseId) { return ExerciseList.FirstOrDefault(e => e.Id == exerciseId)?.Name ?? "Exercise"; } private void AbortRun() { ActiveRun = null; RunEntries = new List(); } private async Task SaveRunAsync() { if (ActiveRun is null) { return; } var request = new RoutineRunRequest(RunEntries); await Api.SaveRunAsync(UserContext.UserId, ActiveRun.Id, request); ActiveRun = null; RunEntries = new List(); } }