Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions ExerciseTracker.selnoom/ExerciseTracker.selnoom.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35818.85 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExerciseTracker.selnoom", "ExerciseTracker.selnoom\ExerciseTracker.selnoom.csproj", "{A48F8834-F068-46C0-9489-D572B2F26B8B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A48F8834-F068-46C0-9489-D572B2F26B8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A48F8834-F068-46C0-9489-D572B2F26B8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A48F8834-F068-46C0-9489-D572B2F26B8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A48F8834-F068-46C0-9489-D572B2F26B8B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {96C93C50-9C5E-48D5-BD19-1A396D9A4806}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using ExerciseTracker.selnoom.Models;
using ExerciseTracker.selnoom.Services;

namespace ExerciseTracker.selnoom.Controllers;

public class WeightExerciseController
{
private readonly WeightExerciseService _weightExerciseService;

public WeightExerciseController(WeightExerciseService weightExerciseService)
{
_weightExerciseService = weightExerciseService;
}

public async Task<WeightExercise?> GetExerciseByIdAsync(int id)
{
return await _weightExerciseService.GetByIdAsync(id);
}

public async Task<List<WeightExercise>> GetExercisesAsync()
{
return await _weightExerciseService.GetExercisesAsync();
}

public async Task<WeightExercise?> CreateExerciseAsync(WeightExercise exercise)
{
return await _weightExerciseService.CreateExerciseAsync(exercise);
}

public async Task<WeightExercise?> UpdateExerciseAsync(WeightExercise exercise)
{
return await _weightExerciseService.UpdateExerciseAsync(exercise);
}

public async Task<string?> DeleteExerciseAsync(int id)
{
return await _weightExerciseService.DeleteExerciseAsync(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using ExerciseTracker.selnoom.Models;
using Microsoft.EntityFrameworkCore;

namespace ExerciseTracker.Data
{
public class ExerciseDbContext : DbContext
{
public ExerciseDbContext(DbContextOptions<ExerciseDbContext> options)
: base(options)
{
}

public DbSet<WeightExercise> Exercises { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using ExerciseTracker.Data;
using ExerciseTracker.selnoom.Models;
using Microsoft.EntityFrameworkCore;

namespace ExerciseTracker.selnoom.Data;

public class WeightExerciseRepository
{
private readonly ExerciseDbContext _exerciseDbContext;

public WeightExerciseRepository(ExerciseDbContext exerciseDbContext)
{
_exerciseDbContext = exerciseDbContext;
}

public async Task<WeightExercise?> GetExerciseByIdAsync(int id)
{
return await _exerciseDbContext.Exercises.FindAsync(id);
}

public async Task<List<WeightExercise>> GetExercisesAsync()
{
return await _exerciseDbContext.Exercises.ToListAsync();
}

public async Task<WeightExercise> CreateExerciseAsync(WeightExercise exercise)
{
var createdExercise = await _exerciseDbContext.Exercises.AddAsync(exercise);
await _exerciseDbContext.SaveChangesAsync();
return createdExercise.Entity;
}

public async Task<WeightExercise?> UpdateExerciseAsync(WeightExercise exercise)
{
WeightExercise? savedExercise = await _exerciseDbContext.Exercises.FindAsync(exercise.Id);

if (savedExercise == null) return null;

_exerciseDbContext.Entry(savedExercise).CurrentValues.SetValues(exercise);
await _exerciseDbContext.SaveChangesAsync();

return savedExercise;
}

public async Task<string?> DeleteExerciseAsync(int id)
{
WeightExercise? savedExercise = await _exerciseDbContext.Exercises.FindAsync(id);

if (savedExercise == null) return null;

_exerciseDbContext.Exercises.Remove(savedExercise);
await _exerciseDbContext.SaveChangesAsync();

return $"Exercise with Id {id} deleted successfully.";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
<PackageReference Include="Spectre.Console" Version="0.49.1" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
103 changes: 103 additions & 0 deletions ExerciseTracker.selnoom/ExerciseTracker.selnoom/Helpers/Validation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using Spectre.Console;

namespace ExerciseTracker.selnoom.Helpers;

class Validation
{
public static string? ValidateTimeInput()
{
string timeInput = AnsiConsole.Ask<string>("Enter date (yyyy-MM-dd HH:mm) or 0 to return to menu:");

if (timeInput == "0")
{
return null;
}

DateTime parsedDate;
while (!DateTime.TryParseExact(timeInput, "yyyy-MM-dd HH:mm", null, System.Globalization.DateTimeStyles.None, out parsedDate))
{
AnsiConsole.MarkupLine("[bold red]Invalid input. Please try again.[/]\n");
timeInput = AnsiConsole.Ask<string>("Enter date (yyyy-MM-dd HH:mm) or 0 to return to menu:");

if (timeInput == "0")
{
return null;
}
}

return parsedDate.ToString("yyyy-MM-dd HH:mm");
}

internal static string? ValidateEndTimeInput(string? startTime)
{
if (startTime == null)
{
return null;
}

while (true)
{
string? endTime = ValidateTimeInput();

if (endTime == null)
{
return null;
}

if (!DateTime.TryParseExact(startTime, "yyyy-MM-dd HH:mm", null, System.Globalization.DateTimeStyles.None, out DateTime parsedStart))
{
AnsiConsole.MarkupLine("[bold red]Invalid start time format.[/]\n");
return null;
}

if (!DateTime.TryParseExact(endTime, "yyyy-MM-dd HH:mm", null, System.Globalization.DateTimeStyles.None, out DateTime parsedEnd))
{
AnsiConsole.MarkupLine("[bold red]Invalid end time format. Please try again.[/]\n");
continue;
}

if (parsedEnd < parsedStart)
{
AnsiConsole.MarkupLine("[bold red]The end time cannot be before the start time. Please try again.[/]\n");
}
else
{
return endTime;
}
}
}

public static double ValidatePositiveDouble(string prompt)
{
double value;
while (true)
{
var input = AnsiConsole.Ask<string>(prompt);
if (double.TryParse(input, out value) && value >= 0)
{
return value;
}
else
{
AnsiConsole.MarkupLine("[red]Please enter a positive number or 0 to return to the menu:[/]");
}
}
}

public static int ValidatePositiveInt(string prompt)
{
int value;
while (true)
{
var input = AnsiConsole.Ask<string>(prompt);
if (int.TryParse(input, out value) && value >= 0)
{
return value;
}
else
{
AnsiConsole.MarkupLine("[red]Please enter positive integer or 0 to return:[/]");
}
}
}
}
Loading