diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.sln b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.sln new file mode 100644 index 00000000..e79ca2fc --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35707.178 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExerciseTracker.HemanthSharma", "ExerciseTracker.HemanthSharma\ExerciseTracker.HemanthSharma.csproj", "{5CAB8E83-D604-455F-ACDF-0166CF575818}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exercisetracker.UI", "Exercisetracker.UI\Exercisetracker.UI.csproj", "{0517394A-116F-4C1C-BCDA-6CFB1C867BB5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5CAB8E83-D604-455F-ACDF-0166CF575818}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5CAB8E83-D604-455F-ACDF-0166CF575818}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5CAB8E83-D604-455F-ACDF-0166CF575818}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5CAB8E83-D604-455F-ACDF-0166CF575818}.Release|Any CPU.Build.0 = Release|Any CPU + {0517394A-116F-4C1C-BCDA-6CFB1C867BB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0517394A-116F-4C1C-BCDA-6CFB1C867BB5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0517394A-116F-4C1C-BCDA-6CFB1C867BB5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0517394A-116F-4C1C-BCDA-6CFB1C867BB5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ContextClass.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ContextClass.cs new file mode 100644 index 00000000..daa0fbc8 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ContextClass.cs @@ -0,0 +1,25 @@ +using ExerciseTracker.Study.Models; +using Microsoft.EntityFrameworkCore; + +namespace ExerciseTracker.HemanthSharma; + +public class ContextClass : DbContext +{ + public ContextClass(DbContextOptions options) : base(options) { } + public DbSet Exercises { get; set; } + public DbSet ExerciseShifts { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.Entity() + .HasKey(x => x.Id); + modelBuilder.Entity() + .HasMany(x => x.ExerciseShifts) + .WithOne(x => x.Exercise) + .HasForeignKey(x => x.ExerciseId); + modelBuilder.Entity() + .HasKey(x => x.Id); + } +} + diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Controllers/ExerciseController.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Controllers/ExerciseController.cs new file mode 100644 index 00000000..4e6258a1 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Controllers/ExerciseController.cs @@ -0,0 +1,60 @@ +using ExerciseTracker.Study.Models; +using ExerciseTracker.Study.Models.DTO; +using ExerciseTracker.Study.Services; +using Microsoft.AspNetCore.Mvc; + +namespace ExerciseTracker.Study.Controllers; + +[Route("api/[controller]")] +[ApiController] +public class ExerciseController : ControllerBase +{ + private readonly IService Service; + public ExerciseController(IService service) + { + Service = service; + } + + [HttpGet] + public async Task>> GetAllExercises() + { + return await Service.GetAll(); + } + + [HttpGet] + [Route("{Id:int}")] + public async Task>> GetExerciseById([FromRoute] int Id) + { + return await Service.GetById(Id); + } + + [HttpPost] + public async Task>> Create([FromBody] ExerciseDto NewExercise) + { + + return await Service.Create(new Exercise + { + Name = NewExercise.Name + } + ); + } + + [HttpPut] + [Route("{Id:int}")] + public async Task>> Update([FromRoute] int Id, [FromBody] ExerciseDto UpdateExerciseDto) + { + Exercise UpdateExercise = new() + { + Id = Id, + Name = UpdateExerciseDto.Name + }; + return await Service.Update(UpdateExercise); + } + + [HttpDelete] + [Route("{Id:int}")] + public async Task>> Delete([FromRoute] int Id) + { + return await Service.Delete(Id); + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Controllers/ExerciseShiftController.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Controllers/ExerciseShiftController.cs new file mode 100644 index 00000000..5c4c38f6 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Controllers/ExerciseShiftController.cs @@ -0,0 +1,76 @@ +using ExerciseTracker.HemanthSharma.HelperMethods; +using ExerciseTracker.Study.Models; +using ExerciseTracker.Study.Models.DTO; +using ExerciseTracker.Study.Services; +using Microsoft.AspNetCore.Mvc; + +namespace ExerciseTracker.Study.Controllers; + +[Route("api/[controller]")] +[ApiController] +public class ExerciseShiftController : ControllerBase +{ + private readonly IService ShiftService; + public ExerciseShiftController(IService service) + { + ShiftService = service; + } + + [HttpGet] + public async Task>> GetAllShifts() + { + return await ShiftService.GetAll(); + } + + [HttpGet] + [Route("{Id:int}")] + public async Task>> GetById([FromRoute] int Id) + { + return await ShiftService.GetById(Id); + } + + [HttpPost] + public async Task>> CreateShift([FromBody] ExerciseShiftDto NewExerciseDto) + { + ExerciseShift NewExerciseShift = HelperClass.ConvertToExercise(NewExerciseDto); + if (NewExerciseShift == null) + { + return new ResponseDto + { + IsSuccess = false, + Data = new List(), + Message = "Bad Data! please check if The Shift Date and Times are in correct format", + ResponseMethod = "Post" + }; + + } + return await ShiftService.Create(NewExerciseShift); + } + + [HttpPut] + [Route("{Id:int}")] + public async Task>> UpdateShift([FromRoute] int Id, [FromBody] ExerciseShiftDto UpdateExerciseDto) + { + ExerciseShift UpdateExerciseShift = HelperClass.ConvertToExercise(UpdateExerciseDto); + if (UpdateExerciseShift == null) + { + return new ResponseDto + { + IsSuccess = false, + Data = new List(), + Message = "Bad Data! please check if The Shift Date and Times are in correct format", + ResponseMethod = "Post" + }; + } + UpdateExerciseShift.Id = Id; + return await ShiftService.Update(UpdateExerciseShift); + } + + [HttpDelete] + [Route("{Id:int}")] + public async Task>> DeleteShift([FromRoute] int Id) + { + + return await ShiftService.Delete(Id); + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/DbSettings.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/DbSettings.cs new file mode 100644 index 00000000..21d711f9 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/DbSettings.cs @@ -0,0 +1,7 @@ +namespace ExerciseTracker.Study; + + public class DbSettings + { + public string Default { get; set; } + } + diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.csproj b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.csproj new file mode 100644 index 00000000..b1529550 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.csproj @@ -0,0 +1,21 @@ + + + + net8.0 + enable + enable + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.http b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.http new file mode 100644 index 00000000..32e933e6 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma.http @@ -0,0 +1,6 @@ +@ExerciseTracker.HemanthSharma_HostAddress = http://localhost:5086 + +GET {{ExerciseTracker.HemanthSharma_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/HelperMethods/HelperClass.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/HelperMethods/HelperClass.cs new file mode 100644 index 00000000..12bdc40b --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/HelperMethods/HelperClass.cs @@ -0,0 +1,30 @@ +using ExerciseTracker.Study.Models; +using ExerciseTracker.Study.Models.DTO; +using ExerciseTracker.Study.ValidationsMethods; + +namespace ExerciseTracker.HemanthSharma.HelperMethods; + +public class HelperClass +{ + public static ExerciseShift ConvertToExercise(ExerciseShiftDto ExerciseDto) + { + if (!Validations.ValidTime(ExerciseDto.StartTime) || !Validations.ValidTime(ExerciseDto.EndTime) || !Validations.ValidDate(ExerciseDto.ExerciseDate)) + { + return null; + } + + DateTime ShiftStartTime = DateTime.ParseExact(ExerciseDto.StartTime, "HH:mm", null); + DateTime ShiftEndTime = DateTime.ParseExact(ExerciseDto.EndTime, "HH:mm", null); + DateTime ShiftDate = DateTime.ParseExact(ExerciseDto.ExerciseDate, "dd-MM-yyyy", null); + + ExerciseShift NewExercise = new ExerciseShift + { + ExerciseId = ExerciseDto.ExerciseId, + StartTime = ShiftStartTime, + EndTime = ShiftEndTime, + Comments = ExerciseDto.Comments, + ExerciseDate = ShiftDate + }; + return NewExercise; + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Interfaces/IEntity.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Interfaces/IEntity.cs new file mode 100644 index 00000000..278482ca --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Interfaces/IEntity.cs @@ -0,0 +1,6 @@ +namespace ExerciseTracker.HemanthSharma.Interfaces; + +public interface IEntity +{ + int Id { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ExerciseDto.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ExerciseDto.cs new file mode 100644 index 00000000..6128a050 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ExerciseDto.cs @@ -0,0 +1,6 @@ +namespace ExerciseTracker.Study.Models.DTO; + +public class ExerciseDto +{ + public string Name { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ExerciseShiftDto.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ExerciseShiftDto.cs new file mode 100644 index 00000000..31422d23 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ExerciseShiftDto.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; + +namespace ExerciseTracker.Study.Models.DTO +{ + public class ExerciseShiftDto + { + public int ExerciseId { get; set; } + [RegularExpression(@"^(0?[0-9]|1[0-9]|2[0-3]):[0-5]\d$")] + public string StartTime { get; set; } + [RegularExpression(@"^(0?[0-9]|1[0-9]|2[0-3]):[0-5]\d$")] + public string EndTime { get; set; } + [RegularExpression(@"^(0[1-9]|[12][0-9]|3[01])-(0[1-9]|1[0-2])-(19|20)\d{2}$")] + public string ExerciseDate { get; set; } + public string? Comments { get; set; } + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ResponseDto.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ResponseDto.cs new file mode 100644 index 00000000..cdd0c753 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/DTO/ResponseDto.cs @@ -0,0 +1,19 @@ +namespace ExerciseTracker.Study.Models.DTO; + +public class ResponseDto +{ + public bool IsSuccess { get; set; } + public string ResponseMethod { get; set; } + public string Message { get; set; } + public List? Data { get; set; } + public ResponseDto CreateResponse(bool IsSuccess, string Message, string method, List? Data) + { + return new ResponseDto + { + IsSuccess = IsSuccess, + Message = Message, + ResponseMethod = method, + Data = Data + }; + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/Exercise.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/Exercise.cs new file mode 100644 index 00000000..68f82845 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/Exercise.cs @@ -0,0 +1,12 @@ +using ExerciseTracker.HemanthSharma.Interfaces; +using System.Text.Json.Serialization; + +namespace ExerciseTracker.Study.Models; + +public class Exercise : IEntity +{ + public int Id { get; set; } + public string Name { get; set; } + [JsonIgnore] + public List? ExerciseShifts { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/ExerciseShift.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/ExerciseShift.cs new file mode 100644 index 00000000..e02415fa --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Models/ExerciseShift.cs @@ -0,0 +1,15 @@ +using ExerciseTracker.HemanthSharma.Interfaces; + +namespace ExerciseTracker.Study.Models; + +public class ExerciseShift : IEntity +{ + public int Id { get; set; } + public int ExerciseId { get; set; } + public DateTime StartTime { get; set; } + public DateTime EndTime { get; set; } + public DateTime ExerciseDate { get; set; } + public int Duration => (int)(EndTime - StartTime).TotalMinutes; + public string? Comments { get; set; } + public Exercise Exercise { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Program.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Program.cs new file mode 100644 index 00000000..9e1708a0 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Program.cs @@ -0,0 +1,48 @@ + +using ExerciseTracker.Study; +using ExerciseTracker.Study.Models; +using ExerciseTracker.Study.Repositories; +using ExerciseTracker.Study.Services; +using Microsoft.EntityFrameworkCore; + +namespace ExerciseTracker.HemanthSharma; + +public class Program +{ + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); + builder.Services.AddScoped, RepositoryDapper>(); + builder.Services.AddScoped, RepositoryClass>(); + builder.Services.AddScoped, ServiceClass>(); + builder.Services.AddScoped, ServiceClass>(); + builder.Services.Configure(builder.Configuration.GetSection("ConnectionStrings")); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseHttpsRedirection(); + + app.UseAuthorization(); + + + app.MapControllers(); + + app.Run(); + } +} + diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Properties/launchSettings.json b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Properties/launchSettings.json new file mode 100644 index 00000000..08d7e6b3 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:4869", + "sslPort": 44382 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5086", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7028;http://localhost:5086", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/IRepository.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/IRepository.cs new file mode 100644 index 00000000..f8f2fda7 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/IRepository.cs @@ -0,0 +1,12 @@ +using ExerciseTracker.Study.Models.DTO; + +namespace ExerciseTracker.Study.Repositories; + +public interface IRepository +{ + Task> GetAll(); + Task> GetById(int Id); + Task> Update(T Entity); + Task> Delete(int Id); + Task> Create(T Entity); +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/RepositoryClass.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/RepositoryClass.cs new file mode 100644 index 00000000..1cdd28a6 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/RepositoryClass.cs @@ -0,0 +1,181 @@ +using ExerciseTracker.HemanthSharma; +using ExerciseTracker.HemanthSharma.Interfaces; +using ExerciseTracker.Study.Models.DTO; +using Microsoft.EntityFrameworkCore; + +namespace ExerciseTracker.Study.Repositories; + +public class RepositoryClass : IRepository where T : class, IEntity +{ + private readonly ContextClass Context; + private readonly DbSet DbSet; + public RepositoryClass(ContextClass _context) + { + Context = _context; + DbSet = _context.Set(); + } + public async Task> Create(T Entity) + { + try + { + var EntityResponse = await DbSet.AddAsync(Entity); + await Context.SaveChangesAsync(); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "POST", + Message = "Successfully Created The Entity", + Data = new List { EntityResponse.Entity } + }; + } + catch (Exception e) + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "POST", + Message = "Error Occured: " + e.Message, + Data = [] + }; + } + } + + public async Task> Delete(int Id) + { + try + { + var Entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(x => x.Id == Id); + if (Entity != null) + { + DbSet.Remove(Entity); + Context.SaveChanges(); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "DELETE", + Message = "Successfully Deleted The Entities", + Data = [Entity] + }; + } + else + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "DELETE", + Message = "No Entity Found to Delete", + Data = [] + }; + } + } + catch (Exception e) + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "DELETE", + Message = "Error Occured: " + e.Message, + Data = [] + }; + } + } + + public async Task> GetAll() + { + try + { + var DataList = await DbSet.ToListAsync(); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "GET", + Message = "Successfully Fetched All The Entities", + Data = DataList + }; + } + catch (Exception e) + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "GET", + Message = "Error Occured: " + e.Message, + Data = [] + }; + } + } + + public async Task> GetById(int Id) + { + try + { + var DataEntity = await DbSet.FindAsync(Id); + if (DataEntity == null) + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "GET", + Message = "No Entity Found for given ID", + Data = new List { DataEntity } + }; + } + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "GET", + Message = "Successfully Fetched The Entity With Id", + Data = new List { DataEntity } + }; + } + catch (Exception e) + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "GET", + Message = "Error Occured: " + e.Message, + Data = [] + }; + } + } + + public async Task> Update(T Entity) + { + try + { + if (await DbSet.AsNoTracking().FirstOrDefaultAsync(x => x.Id == Entity.Id) != null) + { + DbSet.Update(Entity); + Context.SaveChanges(); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "PUT", + Message = "Successfully Updated The Entities", + Data = [Entity] + }; + } + else + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "PUT", + Message = "No Entity Found to Update", + Data = [] + }; + } + } + catch (Exception e) + { + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "PUT", + Message = "Error Occured: " + e.Message, + Data = [] + }; + } + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/RepositoryDapper.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/RepositoryDapper.cs new file mode 100644 index 00000000..f449118c --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Repositories/RepositoryDapper.cs @@ -0,0 +1,175 @@ +using Dapper; +using ExerciseTracker.Study.Models; +using ExerciseTracker.Study.Models.DTO; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Options; +using Spectre.Console; + +namespace ExerciseTracker.Study.Repositories; + +public class RepositoryDapper : IRepository +{ + private string ConnectionString { get; set; } + private DbSettings options { get; set; } + public RepositoryDapper(IOptions _options) + { + options = _options.Value; + ConnectionString = options.Default; + } + + public async Task> Create(Exercise Entity) + { + AnsiConsole.MarkupLine($"[Yellow]Creating The Exercise[darkblue] {Entity.Name}[/] Through[/] [orange3]Dapper[/]"); + try + { + using (SqlConnection conn = new(ConnectionString)) + { + string CreateQuery = "Insert Into Exercises([Name]) Values(@Name);"; + int RowsAffected = conn.Execute(CreateQuery, new { Name = Entity.Name }); + AnsiConsole.MarkupLine($"The Following Rows are Affected {RowsAffected}"); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "POST", + Data = [Entity], + Message = "Successfully Created Entity using Dapper" + }; + } + } + catch (Exception e) + { + AnsiConsole.MarkupLine($"Something Wrong {e.Message}"); + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "POST", + Data = [], + Message = e.Message + }; + } + } + + public async Task> Delete(int Id) + { + AnsiConsole.MarkupLine($"[Yellow]Deleting The Exercise[darkblue] [/] Through[/] [orange3]Dapper[/]"); + try + { + using (SqlConnection conn = new(ConnectionString)) + { + string DeleteQuery = "Delete from Exercises where Id=@id ;"; + int RowsAffected = conn.Execute(DeleteQuery, new { id = Id }); + AnsiConsole.MarkupLine($"The Following Rows are Affected {RowsAffected}"); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "DELETE", + Data = [], + Message = "Successfully Deleted Entity using Dapper" + }; + } + } + catch (Exception e) + { + AnsiConsole.MarkupLine($"Something Wrong {e.Message}"); + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "DELETE", + Data = [], + Message = e.Message + }; + } + } + + public async Task> GetAll() + { + try + { + using (SqlConnection conn = new(ConnectionString)) + { + string GetAllQuery = "Select * from Exercises ;"; + List Exercises = conn.Query(GetAllQuery).ToList(); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "GET", + Data = Exercises, + Message = "Successfully Retrieved All the Entities using Dapper" + }; + } + } + catch (Exception e) + { + AnsiConsole.MarkupLine($"Something Wrong {e.Message}"); + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "GET", + Data = [], + Message = e.Message + }; + } + } + + public async Task> GetById(int Id) + { + try + { + using (SqlConnection conn = new(ConnectionString)) + { + string GetQueryById = "Select * from Exercises where Id=@id ;"; + List Exercises = conn.Query(GetQueryById, new { id = Id }).ToList(); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "GET", + Data = Exercises, + Message = "Successfully Retrieved All the Entities using Dapper" + }; + } + } + catch (Exception e) + { + AnsiConsole.MarkupLine($"Something Wrong {e.Message}"); + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "GET", + Data = [], + Message = e.Message + }; + } + } + + public async Task> Update(Exercise Entity) + { + try + { + using (SqlConnection conn = new(ConnectionString)) + { + string UpdateQuery = "Update Exercises" + + " set Name=@name where Id=@id;"; + int RowsAffected = conn.Execute(UpdateQuery, new { Name = Entity.Name, id = Entity.Id }); + AnsiConsole.MarkupLine($"The Following Rows are Affected {RowsAffected}"); + return new ResponseDto + { + IsSuccess = true, + ResponseMethod = "PUT", + Data = [Entity], + Message = "Successfully Updated Entity using Dapper" + }; + } + } + catch (Exception e) + { + AnsiConsole.MarkupLine($"Something Wrong {e.Message}"); + return new ResponseDto + { + IsSuccess = false, + ResponseMethod = "PUT", + Data = [], + Message = e.Message + }; + } + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Services/IService.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Services/IService.cs new file mode 100644 index 00000000..281a8797 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Services/IService.cs @@ -0,0 +1,12 @@ +using ExerciseTracker.Study.Models.DTO; + +namespace ExerciseTracker.Study.Services; + +public interface IService +{ + Task> GetAll(); + Task> GetById(int Id); + Task> Update(T Entity); + Task> Delete(int Id); + Task> Create(T Entity); +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Services/ServiceClass.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Services/ServiceClass.cs new file mode 100644 index 00000000..108d33b7 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/Services/ServiceClass.cs @@ -0,0 +1,37 @@ +using ExerciseTracker.Study.Models.DTO; +using ExerciseTracker.Study.Repositories; + +namespace ExerciseTracker.Study.Services; + +public class ServiceClass : IService where T : class +{ + private readonly IRepository Repo; + public ServiceClass(IRepository _repo) + { + Repo = _repo; + } + public async Task> Create(T Entity) + { + return await Repo.Create(Entity); + } + + public async Task> Delete(int Id) + { + return await Repo.Delete(Id); + } + + public async Task> GetAll() + { + return await Repo.GetAll(); + } + + public async Task> GetById(int Id) + { + return await Repo.GetById(Id); + } + + public async Task> Update(T Entity) + { + return await Repo.Update(Entity); + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ValidationsMethods/Validations.cs b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ValidationsMethods/Validations.cs new file mode 100644 index 00000000..764b53af --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/ValidationsMethods/Validations.cs @@ -0,0 +1,16 @@ +using System.Globalization; + +namespace ExerciseTracker.Study.ValidationsMethods; + + public class Validations + { + public static bool ValidDate(string Datestring) + { + return DateTime.TryParseExact(Datestring, "dd-MM-yyyy", null, DateTimeStyles.None, out DateTime ShiftDate); + } + public static bool ValidTime(string Timestring) + { + return DateTime.TryParseExact(Timestring, "HH:mm", null, DateTimeStyles.None, out DateTime ShiftDate); + } + } + diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/appsettings.Development.json b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/appsettings.json b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/appsettings.json new file mode 100644 index 00000000..455052f1 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/ExerciseTracker.HemanthSharma/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "Default": "Data Source=DESKTOP-3Q1SB5N\\SQLEXPRESS; Integrated Security= true; TrustServerCertificate=true; Initial Catalog=ExerciseTracker;" + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Exercisetracker.UI.csproj b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Exercisetracker.UI.csproj new file mode 100644 index 00000000..1f9406f0 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Exercisetracker.UI.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/HelperMethods.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/HelperMethods.cs new file mode 100644 index 00000000..d19f760a --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/HelperMethods.cs @@ -0,0 +1,15 @@ +using ExerciseTracker.UI.Models; +using System.Globalization; + +namespace ExerciseTracker.UI; + +internal static class HelperMethods +{ + public static ExerciseShiftDto RefineExerciseShift(ExerciseShiftDto Shift) + { + Shift.StartTime = (DateTime.ParseExact(Shift.StartTime, "HH:mm", null, DateTimeStyles.None)).ToString("HH:mm"); + Shift.EndTime = (DateTime.ParseExact(Shift.EndTime, "HH:mm", null, DateTimeStyles.None)).ToString("HH:mm"); + Shift.ExerciseDate = (DateTime.Parse(Shift.ExerciseDate)).ToString("dd-MM-yyyy"); + return Shift; + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/HttpClientService.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/HttpClientService.cs new file mode 100644 index 00000000..b22958a4 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/HttpClientService.cs @@ -0,0 +1,21 @@ +using System.Configuration; + +namespace ExerciseTracker.UI; + +public class HttpClientService +{ + private string BaseUrl { get; set; } + public HttpClientService() + { + BaseUrl = ConfigurationManager.AppSettings["BaseUrl"]; + } + public string GetBaseUrl() + { + return BaseUrl; + } + public HttpClient GetHttpClient() + { + HttpClient client = new HttpClient(); + return client; + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/Exercise.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/Exercise.cs new file mode 100644 index 00000000..dc3ea596 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/Exercise.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace ExerciseTracker.UI.Models; + +public class Exercise +{ + [property: JsonPropertyName("id")] + public int? id { get; set; } + [property: JsonPropertyName("name")] + public string name { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseDto.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseDto.cs new file mode 100644 index 00000000..bd1eaeba --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseDto.cs @@ -0,0 +1,6 @@ +namespace ExerciseTracker.UI.Models; + +public class ExerciseDto +{ + public string Name { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseShift.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseShift.cs new file mode 100644 index 00000000..c658c46e --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseShift.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace ExerciseTracker.UI.Models; + +public class ExerciseShift +{ + [property: JsonPropertyName("id")] + public int? Id { get; set; } + [property: JsonPropertyName("exerciseId")] + public int ExerciseId { get; set; } + [property: JsonPropertyName("startTime")] + public DateTime StartTime { get; set; } + [property: JsonPropertyName("endTime")] + public DateTime EndTime { get; set; } + [property: JsonPropertyName("exerciseDate")] + public DateTime ExerciseDate { get; set; } + [property: JsonPropertyName("duration")] + public int? Duration { get; set; } + [property: JsonPropertyName("comments")] + public string? Comments { get; set; } + +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseShiftDto.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseShiftDto.cs new file mode 100644 index 00000000..9faf2a56 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ExerciseShiftDto.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace ExerciseTracker.UI.Models; + +public class ExerciseShiftDto +{ + [property: JsonPropertyName("id")] + public int? Id { get; set; } + [property: JsonPropertyName("exerciseId")] + public int ExerciseId { get; set; } + [property: JsonPropertyName("startTime")] + public string StartTime { get; set; } + [property: JsonPropertyName("endTime")] + public string EndTime { get; set; } + [property: JsonPropertyName("exerciseDate")] + public string ExerciseDate { get; set; } + [property: JsonPropertyName("comments")] + public string? Comments { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ResponseDto.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ResponseDto.cs new file mode 100644 index 00000000..8952e9af --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Models/ResponseDto.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace ExerciseTracker.UI.Models; + +public class ResponseDto where T : class +{ + [property: JsonPropertyName("isSuccess")] + public bool IsSuccess { get; set; } + [property: JsonPropertyName("responseMethod")] + public string ResponseMethod { get; set; } + [property: JsonPropertyName("message")] + public string Message { get; set; } + [property: JsonPropertyName("data")] + public List? Data { get; set; } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Program.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Program.cs new file mode 100644 index 00000000..5bf1d461 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Program.cs @@ -0,0 +1,12 @@ +using ExerciseTracker.UI; + +namespace Exercisetracker.UI; + +internal class Program +{ + static void Main(string[] args) + { + bool isRunning = true; + UserInterface.MainMenu(); + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Repositories/Repository.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Repositories/Repository.cs new file mode 100644 index 00000000..570f98fd --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Repositories/Repository.cs @@ -0,0 +1,144 @@ +using ExerciseTracker.UI.Models; +using System.Net.Http.Json; +using System.Text.Json; + +namespace ExerciseTracker.UI.Repositories; + +public class Repository where T : class +{ + public string BaseUrl { get; set; } + HttpClientService ClientService = new(); + HttpClient Client; + public Repository() + { + if (typeof(T).Name == "ExerciseShiftDto") + { + BaseUrl = ClientService.GetBaseUrl() + "ExerciseShift"; + } + else + { + BaseUrl = ClientService.GetBaseUrl() + typeof(T).Name; + } + Client = ClientService.GetHttpClient(); + } + + public async Task> GetAllEntities() + { + try + { + using (var response = await Client.GetStreamAsync(BaseUrl)) + { + ResponseDto GetResponse = JsonSerializer.Deserialize>(response); + return GetResponse; + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return new ResponseDto + { + IsSuccess = false, + Message = e.Message, + ResponseMethod = "GET", + Data = [] + }; + } + } + + public async Task> GetEntiryById(int? Id) + { + try + { + using (var response = await Client.GetStreamAsync(BaseUrl + $"/{Id}")) + { + ResponseDto GetResponse = JsonSerializer.Deserialize>(response); + return GetResponse; + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return new ResponseDto + { + IsSuccess = false, + Message = e.Message, + ResponseMethod = "GET", + Data = [] + }; + } + } + + public async Task> CreateEntity(T Entity) + { + try + { + var response = await Client.PostAsJsonAsync(BaseUrl, Entity); + using (var StreamResponse = await response.Content.ReadAsStreamAsync()) + { + ResponseDto Response = await JsonSerializer.DeserializeAsync>(StreamResponse); + return Response; + } + + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return new ResponseDto + { + IsSuccess = false, + Message = e.Message, + ResponseMethod = "POST", + Data = [] + }; + } + } + + + public async Task> UpdateEntity(T Entity, int? Id) + { + try + { + var response = await Client.PutAsJsonAsync(BaseUrl + $"/{Id}", Entity); + using (var StreamResponse = await response.Content.ReadAsStreamAsync()) + { + ResponseDto Response = await JsonSerializer.DeserializeAsync>(StreamResponse); + return Response; + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return new ResponseDto + { + IsSuccess = false, + Message = e.Message, + ResponseMethod = "PUT", + Data = [] + }; + } + } + + public async Task> DeleteEntity(int? Id) + { + try + { + var response = await Client.DeleteAsync(BaseUrl + $"/{Id}"); + using (var StreamResponse = await response.Content.ReadAsStreamAsync()) + { + ResponseDto Response = await JsonSerializer.DeserializeAsync>(StreamResponse); + return Response; + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return new ResponseDto + { + IsSuccess = false, + Message = e.Message, + ResponseMethod = "DELETE", + Data = [] + }; + } + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Services/ExerciseService.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Services/ExerciseService.cs new file mode 100644 index 00000000..871eead7 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Services/ExerciseService.cs @@ -0,0 +1,47 @@ +using ExerciseTracker.UI.Models; +using ExerciseTracker.UI.Repositories; + +namespace ExerciseTracker.UI.Services; + +public class ExerciseService +{ + private static readonly Repository Repo = new Repository(); + public static void CreateExercise() + { + Exercise NewExercise = UserInputs.GetNewExercise(); + ResponseDto CreatedExercise = Repo.CreateEntity(NewExercise).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(CreatedExercise); + } + + public static void DeleteExercise() + { + List Exercises = Repo.GetAllEntities().GetAwaiter().GetResult().Data; + int? UserChoice = UserInputs.GetExerciseById(Exercises); + ResponseDto DeleteResponse = Repo.DeleteEntity(UserChoice).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(DeleteResponse); + } + + public static void GetAllExercises() + { + ResponseDto Response = Repo.GetAllEntities().GetAwaiter().GetResult(); + UserOutputs.ShowResponse(Response); + } + + public static void GetSingleExercise() + { + List Exercises = Repo.GetAllEntities().GetAwaiter().GetResult().Data; + int? UserChoice = UserInputs.GetExerciseById(Exercises); + ResponseDto Response = Repo.GetEntiryById(UserChoice).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(Response); + } + + public static void UpdateExercise() + { + List Exercises = Repo.GetAllEntities().GetAwaiter().GetResult().Data; + int? UserChoice = UserInputs.GetExerciseById(Exercises); + ResponseDto Response = Repo.GetEntiryById(UserChoice).GetAwaiter().GetResult(); + Exercise UpdatedExercise = UserInputs.GetUpdatedEntity(Response.Data); + ResponseDto UpdatedResponse = Repo.UpdateEntity(UpdatedExercise, UserChoice).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(UpdatedResponse); + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Services/ShiftService.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Services/ShiftService.cs new file mode 100644 index 00000000..56f5e296 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Services/ShiftService.cs @@ -0,0 +1,64 @@ +using ExerciseTracker.UI.Models; +using ExerciseTracker.UI.Repositories; + +namespace ExerciseTracker.UI.Services; + +public static class ShiftService +{ + public static readonly Repository Repo = new Repository(); + public static readonly Repository ExerciseRepo = new Repository(); + public static List GetAvailableExercises() + { + ResponseDto ExercisesResponse = ExerciseRepo.GetAllEntities().GetAwaiter().GetResult(); + return ExercisesResponse.Data; + } + + public static void CreateShift() + { + List AvailableExercises = GetAvailableExercises(); + ExerciseShiftDto NewExercise = UserInputs.GetNewShift(AvailableExercises); + ResponseDto CreateResponse = Repo.CreateEntity(NewExercise).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(CreateResponse); + } + + public static void DeleteShift() + { + ResponseDto ShiftsList = Repo.GetAllEntities().GetAwaiter().GetResult(); + int SelectedShiftId = UserInputs.GetShiftById(ShiftsList.Data); + if (SelectedShiftId == -1) + { + return; + } + ResponseDto DeleteShiftRsponse = Repo.DeleteEntity(SelectedShiftId).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(DeleteShiftRsponse); + } + + public static void GetAllShifts() + { + ResponseDto ShiftList = Repo.GetAllEntities().GetAwaiter().GetResult(); + UserOutputs.ShowResponse(ShiftList); + } + + public static void GetSingleShift() + { + ResponseDto ShiftsList = Repo.GetAllEntities().GetAwaiter().GetResult(); + int SelectedShiftId = UserInputs.GetShiftById(ShiftsList.Data); + if (SelectedShiftId == -1) + { + return; + } + ResponseDto ShiftByIdRsponse = Repo.GetEntiryById(SelectedShiftId).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(ShiftByIdRsponse); + } + + public static void UpdateShift() + { + List ExerciseShifts = Repo.GetAllEntities().GetAwaiter().GetResult().Data; + int? UserChoice = UserInputs.GetShiftById(ExerciseShifts); + ResponseDto Response = Repo.GetEntiryById(UserChoice).GetAwaiter().GetResult(); + ExerciseShiftDto UpdatedExerciseShift = UserInputs.GetUpdatedEntity(Response.Data); + UpdatedExerciseShift = HelperMethods.RefineExerciseShift(UpdatedExerciseShift); + ResponseDto UpdateResponse = Repo.UpdateEntity(UpdatedExerciseShift, UserChoice).GetAwaiter().GetResult(); + UserOutputs.ShowResponse(UpdateResponse); + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserInputs.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserInputs.cs new file mode 100644 index 00000000..18ba2708 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserInputs.cs @@ -0,0 +1,168 @@ +using ExerciseTracker.UI.Models; +using ExerciseTracker.UI.Repositories; +using Spectre.Console; + +namespace ExerciseTracker.UI; + +public class UserInputs where T : class +{ + internal static int? GetExerciseById(List Entities) + { + List UserChoices = new(); + + UserChoices = Entities.Select(x => x.name).ToList(); + + var UserOption = AnsiConsole.Prompt(new SelectionPrompt().Title("Please Choose an option") + .AddChoices(UserChoices)); + return Entities.Where(x => x.name == UserOption).Select(x => x.id).FirstOrDefault(); + } + + internal static int GetShiftById(List Entities) + { + if (Entities.Count() == 0) + { + AnsiConsole.MarkupLine("[pink3] No Entities Found!!![/]"); + Console.WriteLine("Click any key to Continue"); + Console.ReadLine(); + return -1; + } + + List UserChoices = new(); + UserChoices = Entities.Select(x => $"ShiftId={x.Id};ShiftDate={x.ExerciseDate};ShiftStartTime={x.StartTime}").ToList(); + var UserOption = AnsiConsole.Prompt(new SelectionPrompt().Title("Please Choose an option") + .AddChoices(UserChoices)); + return int.Parse(UserOption.Split(";")[0].Split("=")[1]); + } + + internal static Exercise GetNewExercise() + { + string Name = AnsiConsole.Ask("[yellow]Enter the [Blue]Name[/] of the Exercise you want to Add:[/]"); + return new Exercise + { + name = Name + }; + } + + internal static T GetUpdatedEntity(List UpdatedList) + { + T UpdatedEntity = Activator.CreateInstance(); + var props = typeof(T).GetProperties(); + string UpdatedValue = ""; + foreach (var prop in props) + { + string PropertyName = prop.Name; + if (PropertyName.ToLower() != "id") + { + var res = AnsiConsole.Confirm($"[fuchsia]Do you want to change the[yellow] {prop.Name}[/] Property:? The Current Value is [aqua]{prop.GetValue(UpdatedList[0])}[/][/]"); + if (res) + { + if (PropertyName.ToLower() == "exerciseid") + { + Repository Repo = new(); + + int? ExerciseId = UserInputs.GetExerciseById(Repo.GetAllEntities().GetAwaiter().GetResult().Data); + UpdatedValue = ExerciseId.ToString(); + + } + else if (PropertyName.ToLower() == "starttime") + { + UpdatedValue = UserInputs.GetShiftTime().ToString("HH:mm"); + } + else if (PropertyName.ToLower() == "endtime") + { + UpdatedValue = UserInputs.GetShiftTime(DateTime.Parse(UpdatedValue)).ToString("HH:mm"); + } + else if (PropertyName.ToLower() == "exercisedate") + { + UpdatedValue = UserInputs.GetShiftDate().ToString("dd-MM-yyyy"); + } + else + { + AnsiConsole.MarkupLine("[olive] Enter the Updated Value:[/]"); + UpdatedValue = Console.ReadLine(); + } + + } + else + { + UpdatedValue = prop.GetValue(UpdatedList[0]).ToString(); + } + if (prop.Name.ToLower() == "exerciseid") + { + prop.SetValue(UpdatedEntity, int.Parse(UpdatedValue)); + } + else + { + prop.SetValue(UpdatedEntity, UpdatedValue); + } + } + } + return UpdatedEntity; + } + + internal static ExerciseShiftDto GetNewShift(List Exercises) + { + AnsiConsole.MarkupLine("[cyan1]Choose the Exercise for which Shift is to be Created:[/]"); + List ExerciseNames = Exercises.Select(x => $"Id:{x.id} ExerciseName:{x.name}").ToList(); + string Userchoice = AnsiConsole.Prompt(new SelectionPrompt() + .Title("Please select an Exercise for the Shift:") + .AddChoices(ExerciseNames)); + int ExerciseId = int.Parse(Userchoice.Split(" ")[0].Split(":")[1]); + AnsiConsole.MarkupLine("[yellow3] Enter startTime of Shift[/]"); + DateTime StartTime = GetShiftTime(); + AnsiConsole.MarkupLine("[yellow3] Enter EndTime of Shift[/]"); + DateTime EndTime = GetShiftTime(StartTime); + DateTime ExerciseDate = GetShiftDate(); + AnsiConsole.MarkupLine("comments for this shift?"); + string? Comments = Console.ReadLine(); + return new ExerciseShiftDto + { + ExerciseId = ExerciseId, + StartTime = StartTime.ToString("HH:mm"), + EndTime = EndTime.ToString("HH:mm"), + ExerciseDate = ExerciseDate.ToString("dd-MM-yyyy"), + Comments = Comments + }; + } + + private static DateTime GetShiftDate() + { + bool res = AnsiConsole.Confirm("[orange4] Do you want to Enter Custom date?[/][chartreuse2](Default value will be Today's Date)[/]"); + DateTime ExerciseDate; + if (res) + { + ExerciseDate = Validations.GetValidDate(); + } + else + { + ExerciseDate = DateTime.Now.Date; + } + return ExerciseDate; + } + + private static DateTime GetShiftTime(DateTime? StartTime = null) + { + DateTime StartTimeValue = DateTime.Now; + bool isTimeValid = true; + if (StartTime != null) + { + StartTimeValue = (DateTime)StartTime; + isTimeValid = false; + + } + DateTime TimeResult = Validations.GetValidTime(); + while (!isTimeValid) + { + if (TimeResult >= StartTime) + { + isTimeValid = true; + } + else + { + AnsiConsole.MarkupLine($"[lightgreen]The StartTime of the Shift is {StartTimeValue.ToShortTimeString()} EndDate Can't be before StartTime [/]"); + TimeResult = Validations.GetValidTime(); + } + } + return TimeResult; + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserInterface.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserInterface.cs new file mode 100644 index 00000000..f7955c40 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserInterface.cs @@ -0,0 +1,106 @@ +using ExerciseTracker.UI.Services; +using Spectre.Console; + +namespace ExerciseTracker.UI; + +public class UserInterface +{ + public static void MainMenu() + { + bool IsAppRunning = true; + while (IsAppRunning) + { + Console.Clear(); + var userOption = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Please select an option") + .AddChoices(["Manage Shifts", "Manage Exercises", "Exit"]) + ); + + switch (userOption) + { + case "Manage Shifts": + ShiftServiceMenu(); + break; + case "Manage Exercises": + ExerciseServiceMenu(); + break; + case "Exit": + IsAppRunning = false; + break; + } + } + } + + private static void ExerciseServiceMenu() + { + bool isAppRunning = true; + while (isAppRunning) + { + Console.Clear(); + var userOption = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Please select an option") + .AddChoices(["ViewAllExercises", "View a single exercise", "Delete a Exercise", "Create a new Exercise", "Update a Exercise", "Exit"]) + ); + + switch (userOption) + { + case "ViewAllExercises": + ExerciseService.GetAllExercises(); + break; + case "View a single exercise": + ExerciseService.GetSingleExercise(); + break; + case "Delete a Exercise": + ExerciseService.DeleteExercise(); + break; + case "Create a new Exercise": + ExerciseService.CreateExercise(); + break; + case "Update a Exercise": + ExerciseService.UpdateExercise(); + break; + case "Exit": + isAppRunning = false; + break; + } + } + } + + private static void ShiftServiceMenu() + { + bool isAppRunning = true; + while (isAppRunning) + { + Console.Clear(); + var userOption = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Please select an option") + .AddChoices(["ViewAllShifts", "View a single Shift", "Delete a shift", "Create a new Shift", "Update a Shift", "Exit"]) + ); + + switch (userOption) + { + case "ViewAllShifts": + ShiftService.GetAllShifts(); + break; + case "View a single Shift": + ShiftService.GetSingleShift(); + break; + case "Delete a shift": + ShiftService.DeleteShift(); + break; + case "Create a new Shift": + ShiftService.CreateShift(); + break; + case "Update a Shift": + ShiftService.UpdateShift(); + break; + case "Exit": + isAppRunning = false; + break; + } + } + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserOutputs.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserOutputs.cs new file mode 100644 index 00000000..9d79c56a --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/UserOutputs.cs @@ -0,0 +1,67 @@ +using ExerciseTracker.UI.Models; +using Spectre.Console; + +namespace ExerciseTracker.UI; + +public static class UserOutputs where T : class +{ + public static void ShowResponse(ResponseDto Response) + { + Console.Clear(); + if (!Response.IsSuccess) + { + string ResponseString = $"[yellow]Response Method:{Response.ResponseMethod}\n[maroon]Reponse Message:{Response.Message}[/][/]"; + var panel = new Panel(ResponseString); + panel.Header = new PanelHeader("[Red]Request Failed!!![/]"); + panel.Border = BoxBorder.Rounded; + panel.Padding = new Padding(2, 2, 2, 2); + AnsiConsole.Write(panel); + Console.ReadLine(); + } + else + { + string ResponseString = $"[yellow]Response Method:{Response.ResponseMethod}\n[green]Reponse Message:{Response.Message}[/][/]"; + var panel = new Panel(ResponseString); + panel.Header = new PanelHeader("[lime]Request Success!!![/]"); + panel.Border = BoxBorder.Rounded; + panel.Padding = new Padding(2, 2, 2, 2); + AnsiConsole.Write(panel); + string Heading = Response.ResponseMethod switch + { + "GET" => "Here is the Entity Details", + "POST" => "Details of the Entity Created", + "PUT" => "Details of the updated Entity", + "DELETE" => "Details of the Entity Deleted", + _ => "Unknown" + }; + + if (Response.Data.Count() == 0) + { + ResponseString = $"[yellow]Response Method:{Response.ResponseMethod}\nCurrently No Data Found For the requested Entityy in DataBase[/]"; + var EmptyMessagePanel = new Panel(ResponseString); + EmptyMessagePanel.Header = new PanelHeader("[lime]Empty Data!!![/]"); + EmptyMessagePanel.Border = BoxBorder.Rounded; + EmptyMessagePanel.Padding = new Padding(2, 2, 2, 2); + AnsiConsole.Write(EmptyMessagePanel); + Console.ReadLine(); + } + else + { + AnsiConsole.MarkupLine(Heading); + Table Responsetable = new Table(); + Responsetable.Title = new TableTitle(typeof(T).Name); + var props = typeof(T).GetProperties().ToList(); + props.ForEach(x => Responsetable.AddColumn(Markup.Escape(x.Name))); + foreach (var ResponseObject in Response.Data) + { + List RowData = new(); + props.ForEach(x => RowData.Add(x.GetValue(ResponseObject).ToString())); + Responsetable.AddRow(RowData.ToArray()); + } + Responsetable.Border = TableBorder.Double; + AnsiConsole.Write(Responsetable); + } + } + Console.ReadLine(); + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Validations.cs b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Validations.cs new file mode 100644 index 00000000..49a10de3 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/Validations.cs @@ -0,0 +1,31 @@ +using Spectre.Console; +using System.Globalization; + +namespace ExerciseTracker.UI; + +internal class Validations +{ + internal static DateTime GetValidDate() + { + AnsiConsole.MarkupLine("[darkred]Enter the Date in 'dd-MM-yyyy' Format:[/]"); + bool res = DateTime.TryParseExact(Console.ReadLine().Trim(), "dd-MM-yyyy", null, DateTimeStyles.None, out DateTime DateResult); + while (!res) + { + AnsiConsole.MarkupLine("[darkred]Enter the Date in correct [yellow] 'dd-MM-yyyy'[/] Format:[/]"); + res = DateTime.TryParseExact(Console.ReadLine().Trim(), "dd-MM-yyyy", null, DateTimeStyles.None, out DateResult); + } + return DateResult; + } + + internal static DateTime GetValidTime() + { + AnsiConsole.MarkupLine("[lightsteelblue]Enter the Time in 'HH:mm' Format:[/]"); + bool res = DateTime.TryParseExact(Console.ReadLine().Trim(), "HH:mm", null, DateTimeStyles.None, out DateTime TimeResult); + while (!res) + { + AnsiConsole.MarkupLine("[red3_1]Enter the Time in correct [yellow] 'HH:mm'[/] Format:[/]"); + res = DateTime.TryParseExact(Console.ReadLine().Trim(), "HH:mm", null, DateTimeStyles.None, out TimeResult); + } + return TimeResult; + } +} diff --git a/ExerciseTracker.HemanthSharma/Exercisetracker.UI/app.config b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/app.config new file mode 100644 index 00000000..9f4162fd --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Exercisetracker.UI/app.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/ExerciseTracker.HemanthSharma/Readme.md b/ExerciseTracker.HemanthSharma/Readme.md new file mode 100644 index 00000000..669e0056 --- /dev/null +++ b/ExerciseTracker.HemanthSharma/Readme.md @@ -0,0 +1,71 @@ +# ExerciseTracker.Study + +## Overview + +**ExerciseTracker.Study** is a C# project designed to help users track and manage their exercise routines efficiently. This application provides tools to log workouts, monitor progress, and analyze fitness trends, making it ideal for individuals and groups aiming to improve their physical health. + +## Features + +- Log daily exercises with details such as type, duration, and intensity +- View and analyze workout history and trends +- Set and track fitness goals +- User-friendly interface +- Data persistence for workout records + +## Getting Started +## Build Instructions +### DataBaseConnectionString +Change the Connection string in appsettings.json in ExerciseTracker API project to map to your local Db and run migration. +### BaseUrl in in Console project +Chnage the BaseUrl in ExerciseTracker.UI project in app.Config file. to point to the localhost port where your webAPI project runs +### Running Both the Projects as Startup Projects +right click on any of project-> Configure StartUp projects-> select Multiple Startup projects-> select both the projects listed as Start projects + +### Prerequisites + +- [.NET SDK](https://dotnet.microsoft.com/download) (version X.X or above) +- A compatible development environment (e.g., Visual Studio, VS Code) + +### Installation + +1. **Clone the repository:** + ```bash + git clone https://github.com/HKHemanthsharma/CodeReviews.Console.ExerciseTracker.git + cd ExerciseTracker.Study + ``` + +2. **Restore dependencies:** + ```bash + dotnet restore + ``` + +3. **Build the project:** + ```bash + dotnet build + ``` + +4. **Run the application:** + ```bash + dotnet run + ``` + +## Usage + +- Launch the application and follow the on-screen instructions to start logging workouts. +- Navigate through features to view progress reports and set new goals. + +## Contributing + +Contributions are welcome! Please open an issue or submit a pull request for any feature requests, bug reports, or improvements. + +## License + +This project is licensed under the [MIT License](LICENSE). + +## Maintainers + +- [HKHemanthsharma](https://github.com/HKHemanthsharma) + +--- + +*Happy exercising!*