diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/MobileAppProject.sln b/MobileAppProject.sln new file mode 100644 index 0000000..6472085 --- /dev/null +++ b/MobileAppProject.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31611.283 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileAppProject", "MobileAppProject\MobileAppProject.csproj", "{DDE78219-BA55-45D2-A656-530F53B0BFA5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDE78219-BA55-45D2-A656-530F53B0BFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDE78219-BA55-45D2-A656-530F53B0BFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDE78219-BA55-45D2-A656-530F53B0BFA5}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {DDE78219-BA55-45D2-A656-530F53B0BFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDE78219-BA55-45D2-A656-530F53B0BFA5}.Release|Any CPU.Build.0 = Release|Any CPU + {DDE78219-BA55-45D2-A656-530F53B0BFA5}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572} + EndGlobalSection +EndGlobal diff --git a/MobileAppProject/App.xaml b/MobileAppProject/App.xaml new file mode 100644 index 0000000..61e6673 --- /dev/null +++ b/MobileAppProject/App.xaml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/MobileAppProject/App.xaml.cs b/MobileAppProject/App.xaml.cs new file mode 100644 index 0000000..5d00bcc --- /dev/null +++ b/MobileAppProject/App.xaml.cs @@ -0,0 +1,13 @@ +using MobileAppProject.View; + +namespace MobileAppProject; + +public partial class App : Application +{ + public App() + { + InitializeComponent(); + + MainPage = new AppShell(); + } +} diff --git a/MobileAppProject/AppShell.xaml b/MobileAppProject/AppShell.xaml new file mode 100644 index 0000000..8dcef44 --- /dev/null +++ b/MobileAppProject/AppShell.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileAppProject/AppShell.xaml.cs b/MobileAppProject/AppShell.xaml.cs new file mode 100644 index 0000000..6c5dbb9 --- /dev/null +++ b/MobileAppProject/AppShell.xaml.cs @@ -0,0 +1,9 @@ +namespace MobileAppProject; + +public partial class AppShell : Shell +{ + public AppShell() + { + InitializeComponent(); + } +} diff --git a/MobileAppProject/AppState.cs b/MobileAppProject/AppState.cs new file mode 100644 index 0000000..58a8267 --- /dev/null +++ b/MobileAppProject/AppState.cs @@ -0,0 +1,12 @@ +using MobileAppProject.Interfaces; +using MobileAppProject.Model; +namespace MobileAppProject +{ + public class AppState : IAppState + { + public User currentUser { get; set; } + public Routine selectedRoutine { get; set; } + public bool routineCreationMode { get; set; } + public AppState() { } + } +} diff --git a/MobileAppProject/Constants.cs b/MobileAppProject/Constants.cs new file mode 100644 index 0000000..2674e66 --- /dev/null +++ b/MobileAppProject/Constants.cs @@ -0,0 +1,19 @@ +using System; + +namespace MobileAppProject +{ + public static class Constants + { + public static string EndpointBase = "https://dc88-5-151-46-84.eu.ngrok.io/"; + + public static class Endpoints + { + public static string Users = "api/User/"; + public static string MuscleGroups = "api/MuscleGroup/"; + public static string Exercises = "api/Exercises/"; + public static string Routines = "api/Routines/"; + public static string RoutineExercises = "api/RoutineExercise/"; + } + + } +} diff --git a/MobileAppProject/Interfaces/IAppState.cs b/MobileAppProject/Interfaces/IAppState.cs new file mode 100644 index 0000000..83ec0a7 --- /dev/null +++ b/MobileAppProject/Interfaces/IAppState.cs @@ -0,0 +1,11 @@ +using MobileAppProject.Model; + +namespace MobileAppProject.Interfaces +{ + public interface IAppState + { + public User currentUser { get; set; } + public Routine selectedRoutine { get; set; } + public bool routineCreationMode { get; set; } + } +} diff --git a/MobileAppProject/Interfaces/IDatabaseService.cs b/MobileAppProject/Interfaces/IDatabaseService.cs new file mode 100644 index 0000000..2e43044 --- /dev/null +++ b/MobileAppProject/Interfaces/IDatabaseService.cs @@ -0,0 +1,13 @@ +using MobileAppProject.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Interfaces +{ + public interface IDatabaseService + { + } +} diff --git a/MobileAppProject/Interfaces/IFacadeService.cs b/MobileAppProject/Interfaces/IFacadeService.cs new file mode 100644 index 0000000..2191b97 --- /dev/null +++ b/MobileAppProject/Interfaces/IFacadeService.cs @@ -0,0 +1,28 @@ +using System; +using MobileAppProject.Model; + +namespace MobileAppProject.Interfaces +{ + public interface IFacadeService + { + public Task> GetUsers(); + public Task> GetAllGroups(); + public Task> GetAllExercises(); + public Task> GetRoutinesByUser(int? id); + public Task> GetExercisesByRoutine(int? id); + + + public Task CreateUser(User user); + public Task CreateRoutine(Routine routine); + + public Task AddRoutineExercise(RoutineExercise routineExercise); + + public Task UpdateRoutineExercise(int? id, RoutineExercise routineExercise); + + public Task UpdateRoutine(int? id, Routine routine); + + public Task DeleteRoutineExercise(int? id); + + public Task DeleteRoutine(int? id); + } +} diff --git a/MobileAppProject/Interfaces/IGymService.cs b/MobileAppProject/Interfaces/IGymService.cs new file mode 100644 index 0000000..2d2f936 --- /dev/null +++ b/MobileAppProject/Interfaces/IGymService.cs @@ -0,0 +1,31 @@ +using MobileAppProject.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Interfaces +{ + public interface IGymService + { + public Task> GetUsers(); + + public Task> GetAllGroups(); + + public Task> GetAllExercises(); + + public Task> GetRoutinesByUser(int? id); + + public Task> GetExercisesByRoutine(int? id); + + public Task CreateUser(User user); + public Task CreateRoutine(Routine routine); + public Task AddRoutineExercise(RoutineExercise routineExercise); + public Task UpdateRoutineExercise(int? id, RoutineExercise routineExercise); + public Task DeleteRoutineExercise(int? id); + public Task DeleteRoutine(int? id); + + public Task UpdateRoutine(int? id, Routine routine); + } +} diff --git a/MobileAppProject/Interfaces/IHasher.cs b/MobileAppProject/Interfaces/IHasher.cs new file mode 100644 index 0000000..71ba697 --- /dev/null +++ b/MobileAppProject/Interfaces/IHasher.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Interfaces +{ + public interface IHasher + { + public string HashPassword(string password, out byte[] passwordsalt); + public bool VerifyPassword(string password, string passwordhash, byte[] passwordsalt); + } +} diff --git a/MobileAppProject/Interfaces/IPopUpService.cs b/MobileAppProject/Interfaces/IPopUpService.cs new file mode 100644 index 0000000..0161bd0 --- /dev/null +++ b/MobileAppProject/Interfaces/IPopUpService.cs @@ -0,0 +1,15 @@ +using CommunityToolkit.Maui.Views; +using MobileAppProject.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Interfaces +{ + public interface IPopUpService + { + public Task PopUp(Popup popup); + } +} diff --git a/MobileAppProject/Interfaces/IUserService.cs b/MobileAppProject/Interfaces/IUserService.cs new file mode 100644 index 0000000..439dc7e --- /dev/null +++ b/MobileAppProject/Interfaces/IUserService.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Interfaces +{ + public interface IUserService + { + public Task> GetUsers(); + } +} diff --git a/MobileAppProject/MauiProgram.cs b/MobileAppProject/MauiProgram.cs new file mode 100644 index 0000000..6a97abc --- /dev/null +++ b/MobileAppProject/MauiProgram.cs @@ -0,0 +1,66 @@ +using Microsoft.Extensions.Logging; +using MobileAppProject.Services; +using MobileAppProject.Interfaces; +using MobileAppProject.Security; +using CommunityToolkit.Maui; +namespace MobileAppProject; + +public static class MauiProgram +{ + public static MauiApp CreateMauiApp() + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .UseMauiCommunityToolkit() + .ConfigureFonts(fonts => + { + fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); + fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); + fonts.AddFont("Fontspring-DEMO-grotesco-black.otf", "Grotesco"); + fonts.AddFont("StayPixelRegular-EaOxl.ttf", "Pixel"); + fonts.AddFont("Pokemon Classic.ttf", "Pokemon"); + fonts.AddFont("Retro Gaming.ttf", "Retro"); + fonts.AddFont("PlayMeGames-Demo.otf", "Game"); + + }) + .RegisterViewsAndViewModels() + .RegisterServices(); +#if DEBUG + builder.Logging.AddDebug(); +#endif + return builder.Build(); + } + + public static MauiAppBuilder RegisterViewsAndViewModels(this MauiAppBuilder mauiAppBuilder) + { + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.LoginViewModel)); + mauiAppBuilder.Services.AddTransient(typeof(View.LoginView)); + mauiAppBuilder.Services.AddTransient(typeof(View.MainView)); + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.MainViewModel)); + mauiAppBuilder.Services.AddTransient(typeof(View.SignUpView)); + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.SignUpViewModel)); + mauiAppBuilder.Services.AddTransient(typeof(View.MuscleGroupView)); + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.MuscleGroupViewModel)); + mauiAppBuilder.Services.AddTransient(typeof(View.ExercisesView)); + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.ExercisesViewModel)); + mauiAppBuilder.Services.AddTransient(typeof(View.ExerciseDetailsView)); + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.ExerciseDetailsViewModel)); + mauiAppBuilder.Services.AddTransient(typeof(View.CreateRoutineView)); + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.CreateRoutineViewModel)); + mauiAppBuilder.Services.AddTransient(typeof(View.RoutineExercisesView)); + mauiAppBuilder.Services.AddTransient(typeof(ViewModel.RoutineExercisesViewModel)); + return mauiAppBuilder; + } + + public static MauiAppBuilder RegisterServices(this MauiAppBuilder mauiAppBuilder) + { + //mauiAppBuilder.Services.AddTransient(); + mauiAppBuilder.Services.AddTransient(); + mauiAppBuilder.Services.AddTransient(); + mauiAppBuilder.Services.AddTransient(); + mauiAppBuilder.Services.AddTransient(); + mauiAppBuilder.Services.AddSingleton(); + return mauiAppBuilder; + } +} diff --git a/MobileAppProject/MobileAppProject.csproj b/MobileAppProject/MobileAppProject.csproj new file mode 100644 index 0000000..793fb80 --- /dev/null +++ b/MobileAppProject/MobileAppProject.csproj @@ -0,0 +1,104 @@ + + + + net7.0-android;net7.0-maccatalyst;net7.0-ios + $(TargetFrameworks);net7.0-windows10.0.19041.0 + + + Exe + MobileAppProject + true + true + enable + + + MobileAppProject + + + com.companyname.mobileappproject + 50b5704d-9fd0-46c3-8ad9-32fc94808763 + + + 1.0 + 1 + + 11.0 + 13.1 + 21.0 + 10.0.17763.0 + 10.0.17763.0 + 6.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LoginView.xaml + + + MainView.xaml + + + SignUpView.xaml + + + UpdateExercisePopUp.xaml + + + + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + + diff --git a/MobileAppProject/Model/Exercise.cs b/MobileAppProject/Model/Exercise.cs new file mode 100644 index 0000000..998762d --- /dev/null +++ b/MobileAppProject/Model/Exercise.cs @@ -0,0 +1,12 @@ + + +namespace MobileAppProject.Model +{ + public class Exercise + { + public int ID { get; set; } + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + public int MuscleGroupID { get; set; } + } +} diff --git a/MobileAppProject/Model/Level.cs b/MobileAppProject/Model/Level.cs new file mode 100644 index 0000000..f44ee08 --- /dev/null +++ b/MobileAppProject/Model/Level.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Model +{ + public class Level + { + public int ID { get; set; } + + public string Name { get; set; } = string.Empty; + + public int MinXP { get; set; } + } +} diff --git a/MobileAppProject/Model/MuscleGroup.cs b/MobileAppProject/Model/MuscleGroup.cs new file mode 100644 index 0000000..4e5690b --- /dev/null +++ b/MobileAppProject/Model/MuscleGroup.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Model +{ + public class MuscleGroup + { + public int ID { get; set; } + public string Name { get; set; } = string.Empty; + //public List Exercises { get; set; } + } +} diff --git a/MobileAppProject/Model/Routine.cs b/MobileAppProject/Model/Routine.cs new file mode 100644 index 0000000..d4f98e7 --- /dev/null +++ b/MobileAppProject/Model/Routine.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Model +{ + public class Routine + { + public int? ID { get; set; } + public string Name { get; set; } + public int? userID { get; set; } + public string Day { get; set; } + } +} diff --git a/MobileAppProject/Model/RoutineExercise.cs b/MobileAppProject/Model/RoutineExercise.cs new file mode 100644 index 0000000..b138d7e --- /dev/null +++ b/MobileAppProject/Model/RoutineExercise.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MobileAppProject.Model +{ + public class RoutineExercise + { + public int? ID { get; set; } + public int? ExerciseID { get; set; } + public int? RoutineID { get; set; } + public int? Sets { get; set; } + public int? Reps { get; set; } + public int? Weight { get; set; } + public Exercise Exercise { get; set; } + } +} diff --git a/MobileAppProject/Model/User.cs b/MobileAppProject/Model/User.cs new file mode 100644 index 0000000..f85ae5a --- /dev/null +++ b/MobileAppProject/Model/User.cs @@ -0,0 +1,29 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace MobileAppProject.Model +{ + public class User + { + public int? ID { get; set; } + public string username { get; set; } = string.Empty; + + public byte[] passwordsalt { get; set; } + + public string passwordhash { get; set; } = string.Empty; + + public string email { get; set; } = string.Empty; + + public int XP { get; set; } + + public int LevelID { get; set; } + + //[JsonIgnore] + //public Level Level { get; set; } + } +} diff --git a/MobileAppProject/Platforms/Android/AndroidManifest.xml b/MobileAppProject/Platforms/Android/AndroidManifest.xml new file mode 100644 index 0000000..e9937ad --- /dev/null +++ b/MobileAppProject/Platforms/Android/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/MobileAppProject/Platforms/Android/MainActivity.cs b/MobileAppProject/Platforms/Android/MainActivity.cs new file mode 100644 index 0000000..0ff5c46 --- /dev/null +++ b/MobileAppProject/Platforms/Android/MainActivity.cs @@ -0,0 +1,10 @@ +using Android.App; +using Android.Content.PM; +using Android.OS; + +namespace MobileAppProject; + +[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] +public class MainActivity : MauiAppCompatActivity +{ +} diff --git a/MobileAppProject/Platforms/Android/MainApplication.cs b/MobileAppProject/Platforms/Android/MainApplication.cs new file mode 100644 index 0000000..df8984b --- /dev/null +++ b/MobileAppProject/Platforms/Android/MainApplication.cs @@ -0,0 +1,15 @@ +using Android.App; +using Android.Runtime; + +namespace MobileAppProject; + +[Application] +public class MainApplication : MauiApplication +{ + public MainApplication(IntPtr handle, JniHandleOwnership ownership) + : base(handle, ownership) + { + } + + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); +} diff --git a/MobileAppProject/Platforms/Android/Resources/values/colors.xml b/MobileAppProject/Platforms/Android/Resources/values/colors.xml new file mode 100644 index 0000000..c04d749 --- /dev/null +++ b/MobileAppProject/Platforms/Android/Resources/values/colors.xml @@ -0,0 +1,6 @@ + + + #512BD4 + #2B0B98 + #2B0B98 + \ No newline at end of file diff --git a/MobileAppProject/Platforms/MacCatalyst/AppDelegate.cs b/MobileAppProject/Platforms/MacCatalyst/AppDelegate.cs new file mode 100644 index 0000000..3d58e36 --- /dev/null +++ b/MobileAppProject/Platforms/MacCatalyst/AppDelegate.cs @@ -0,0 +1,9 @@ +using Foundation; + +namespace MobileAppProject; + +[Register("AppDelegate")] +public class AppDelegate : MauiUIApplicationDelegate +{ + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); +} diff --git a/MobileAppProject/Platforms/MacCatalyst/Info.plist b/MobileAppProject/Platforms/MacCatalyst/Info.plist new file mode 100644 index 0000000..c96dd0a --- /dev/null +++ b/MobileAppProject/Platforms/MacCatalyst/Info.plist @@ -0,0 +1,30 @@ + + + + + UIDeviceFamily + + 1 + 2 + + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/appicon.appiconset + + diff --git a/MobileAppProject/Platforms/MacCatalyst/Program.cs b/MobileAppProject/Platforms/MacCatalyst/Program.cs new file mode 100644 index 0000000..ced6f3a --- /dev/null +++ b/MobileAppProject/Platforms/MacCatalyst/Program.cs @@ -0,0 +1,15 @@ +using ObjCRuntime; +using UIKit; + +namespace MobileAppProject; + +public class Program +{ + // This is the main entry point of the application. + static void Main(string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main(args, null, typeof(AppDelegate)); + } +} diff --git a/MobileAppProject/Platforms/Tizen/Main.cs b/MobileAppProject/Platforms/Tizen/Main.cs new file mode 100644 index 0000000..a97d060 --- /dev/null +++ b/MobileAppProject/Platforms/Tizen/Main.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.Maui; +using Microsoft.Maui.Hosting; + +namespace MobileAppProject; + +class Program : MauiApplication +{ + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } +} diff --git a/MobileAppProject/Platforms/Tizen/tizen-manifest.xml b/MobileAppProject/Platforms/Tizen/tizen-manifest.xml new file mode 100644 index 0000000..3efa26b --- /dev/null +++ b/MobileAppProject/Platforms/Tizen/tizen-manifest.xml @@ -0,0 +1,15 @@ + + + + + + maui-appicon-placeholder + + + + + http://tizen.org/privilege/internet + + + + \ No newline at end of file diff --git a/MobileAppProject/Platforms/Windows/App.xaml b/MobileAppProject/Platforms/Windows/App.xaml new file mode 100644 index 0000000..89e7c3b --- /dev/null +++ b/MobileAppProject/Platforms/Windows/App.xaml @@ -0,0 +1,8 @@ + + + diff --git a/MobileAppProject/Platforms/Windows/App.xaml.cs b/MobileAppProject/Platforms/Windows/App.xaml.cs new file mode 100644 index 0000000..d0ff8ed --- /dev/null +++ b/MobileAppProject/Platforms/Windows/App.xaml.cs @@ -0,0 +1,24 @@ +using Microsoft.UI.Xaml; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace MobileAppProject.WinUI; + +/// +/// Provides application-specific behavior to supplement the default Application class. +/// +public partial class App : MauiWinUIApplication +{ + /// + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// + public App() + { + this.InitializeComponent(); + } + + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); +} + diff --git a/MobileAppProject/Platforms/Windows/Package.appxmanifest b/MobileAppProject/Platforms/Windows/Package.appxmanifest new file mode 100644 index 0000000..02cc794 --- /dev/null +++ b/MobileAppProject/Platforms/Windows/Package.appxmanifest @@ -0,0 +1,46 @@ + + + + + + + + + $placeholder$ + User Name + $placeholder$.png + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileAppProject/Platforms/Windows/app.manifest b/MobileAppProject/Platforms/Windows/app.manifest new file mode 100644 index 0000000..031912f --- /dev/null +++ b/MobileAppProject/Platforms/Windows/app.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + + diff --git a/MobileAppProject/Platforms/iOS/AppDelegate.cs b/MobileAppProject/Platforms/iOS/AppDelegate.cs new file mode 100644 index 0000000..3d58e36 --- /dev/null +++ b/MobileAppProject/Platforms/iOS/AppDelegate.cs @@ -0,0 +1,9 @@ +using Foundation; + +namespace MobileAppProject; + +[Register("AppDelegate")] +public class AppDelegate : MauiUIApplicationDelegate +{ + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); +} diff --git a/MobileAppProject/Platforms/iOS/Info.plist b/MobileAppProject/Platforms/iOS/Info.plist new file mode 100644 index 0000000..0004a4f --- /dev/null +++ b/MobileAppProject/Platforms/iOS/Info.plist @@ -0,0 +1,32 @@ + + + + + LSRequiresIPhoneOS + + UIDeviceFamily + + 1 + 2 + + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/appicon.appiconset + + diff --git a/MobileAppProject/Platforms/iOS/Program.cs b/MobileAppProject/Platforms/iOS/Program.cs new file mode 100644 index 0000000..ced6f3a --- /dev/null +++ b/MobileAppProject/Platforms/iOS/Program.cs @@ -0,0 +1,15 @@ +using ObjCRuntime; +using UIKit; + +namespace MobileAppProject; + +public class Program +{ + // This is the main entry point of the application. + static void Main(string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main(args, null, typeof(AppDelegate)); + } +} diff --git a/MobileAppProject/Properties/launchSettings.json b/MobileAppProject/Properties/launchSettings.json new file mode 100644 index 0000000..edf8aad --- /dev/null +++ b/MobileAppProject/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Windows Machine": { + "commandName": "MsixPackage", + "nativeDebugging": false + } + } +} \ No newline at end of file diff --git a/MobileAppProject/Resources/AppIcon/appicon.svg b/MobileAppProject/Resources/AppIcon/appicon.svg new file mode 100644 index 0000000..9d63b65 --- /dev/null +++ b/MobileAppProject/Resources/AppIcon/appicon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MobileAppProject/Resources/AppIcon/appiconfg.svg b/MobileAppProject/Resources/AppIcon/appiconfg.svg new file mode 100644 index 0000000..21dfb25 --- /dev/null +++ b/MobileAppProject/Resources/AppIcon/appiconfg.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/MobileAppProject/Resources/Fonts/Fontspring-DEMO-grotesco-black.otf b/MobileAppProject/Resources/Fonts/Fontspring-DEMO-grotesco-black.otf new file mode 100644 index 0000000..3cd4ce5 Binary files /dev/null and b/MobileAppProject/Resources/Fonts/Fontspring-DEMO-grotesco-black.otf differ diff --git a/MobileAppProject/Resources/Fonts/OpenSans-Regular.ttf b/MobileAppProject/Resources/Fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000..e2644a5 Binary files /dev/null and b/MobileAppProject/Resources/Fonts/OpenSans-Regular.ttf differ diff --git a/MobileAppProject/Resources/Fonts/OpenSans-Semibold.ttf b/MobileAppProject/Resources/Fonts/OpenSans-Semibold.ttf new file mode 100644 index 0000000..f75b525 Binary files /dev/null and b/MobileAppProject/Resources/Fonts/OpenSans-Semibold.ttf differ diff --git a/MobileAppProject/Resources/Fonts/PlayMeGames-Demo.otf b/MobileAppProject/Resources/Fonts/PlayMeGames-Demo.otf new file mode 100644 index 0000000..2e54e03 Binary files /dev/null and b/MobileAppProject/Resources/Fonts/PlayMeGames-Demo.otf differ diff --git a/MobileAppProject/Resources/Fonts/Pokemon Classic.ttf b/MobileAppProject/Resources/Fonts/Pokemon Classic.ttf new file mode 100644 index 0000000..f2cb4ef Binary files /dev/null and b/MobileAppProject/Resources/Fonts/Pokemon Classic.ttf differ diff --git a/MobileAppProject/Resources/Fonts/Retro Gaming.ttf b/MobileAppProject/Resources/Fonts/Retro Gaming.ttf new file mode 100644 index 0000000..0dca996 Binary files /dev/null and b/MobileAppProject/Resources/Fonts/Retro Gaming.ttf differ diff --git a/MobileAppProject/Resources/Fonts/StayPixelRegular-EaOxl.ttf b/MobileAppProject/Resources/Fonts/StayPixelRegular-EaOxl.ttf new file mode 100644 index 0000000..8c8d34d Binary files /dev/null and b/MobileAppProject/Resources/Fonts/StayPixelRegular-EaOxl.ttf differ diff --git a/MobileAppProject/Resources/Images/dotnet_bot.svg b/MobileAppProject/Resources/Images/dotnet_bot.svg new file mode 100644 index 0000000..abfaff2 --- /dev/null +++ b/MobileAppProject/Resources/Images/dotnet_bot.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileAppProject/Resources/Raw/AboutAssets.txt b/MobileAppProject/Resources/Raw/AboutAssets.txt new file mode 100644 index 0000000..15d6244 --- /dev/null +++ b/MobileAppProject/Resources/Raw/AboutAssets.txt @@ -0,0 +1,15 @@ +Any raw assets you want to be deployed with your application can be placed in +this directory (and child directories). Deployment of the asset to your application +is automatically handled by the following `MauiAsset` Build Action within your `.csproj`. + + + +These files will be deployed with you package and will be accessible using Essentials: + + async Task LoadMauiAsset() + { + using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt"); + using var reader = new StreamReader(stream); + + var contents = reader.ReadToEnd(); + } diff --git a/MobileAppProject/Resources/Splash/splash.svg b/MobileAppProject/Resources/Splash/splash.svg new file mode 100644 index 0000000..21dfb25 --- /dev/null +++ b/MobileAppProject/Resources/Splash/splash.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/MobileAppProject/Resources/Styles/Colors.xaml b/MobileAppProject/Resources/Styles/Colors.xaml new file mode 100644 index 0000000..364a518 --- /dev/null +++ b/MobileAppProject/Resources/Styles/Colors.xaml @@ -0,0 +1,44 @@ + + + + + black + black + #2B0B98 + White + Black + #E1E1E1 + #C8C8C8 + #ACACAC + #919191 + #6E6E6E + #404040 + #212121 + #141414 + + + + + + + + + + + + + + + #F7B548 + #FFD590 + #FFE5B9 + #28C2D1 + #7BDDEF + #C3F2F4 + #3E8EED + #72ACF1 + #A7CBF6 + + \ No newline at end of file diff --git a/MobileAppProject/Resources/Styles/Styles.xaml b/MobileAppProject/Resources/Styles/Styles.xaml new file mode 100644 index 0000000..a5ffbc0 --- /dev/null +++ b/MobileAppProject/Resources/Styles/Styles.xaml @@ -0,0 +1,406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileAppProject/Security/Hasher.cs b/MobileAppProject/Security/Hasher.cs new file mode 100644 index 0000000..b5da2a8 --- /dev/null +++ b/MobileAppProject/Security/Hasher.cs @@ -0,0 +1,35 @@ +using MobileAppProject.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +//https://code-maze.com/csharp-hashing-salting-passwords-best-practices/ +namespace MobileAppProject.Security +{ + public class Hasher : IHasher + { + const int keySize = 64; + const int iterations = 350000; + HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA512; + + public string HashPassword(string password, out byte[] passwordsalt) + { + passwordsalt = RandomNumberGenerator.GetBytes(keySize); + var hash = Rfc2898DeriveBytes.Pbkdf2( + Encoding.UTF8.GetBytes(password), + passwordsalt, + iterations, + hashAlgorithm, + keySize); + return Convert.ToHexString(hash); + } + + public bool VerifyPassword(string password, string passwordhash, byte[] passwordsalt) + { + var hashToCompare = Rfc2898DeriveBytes.Pbkdf2(password, passwordsalt, iterations, hashAlgorithm, keySize); + return hashToCompare.SequenceEqual(Convert.FromHexString(passwordhash)); + } + } +} diff --git a/MobileAppProject/Services/DatabaseService.cs b/MobileAppProject/Services/DatabaseService.cs new file mode 100644 index 0000000..0a34e21 --- /dev/null +++ b/MobileAppProject/Services/DatabaseService.cs @@ -0,0 +1,18 @@ +using MobileAppProject.Model; +using MobileAppProject.Interfaces; + +namespace MobileAppProject.Services +{ + public class DatabaseService : IDatabaseService + { + + public DatabaseService() { + } + + + + + + + } +} diff --git a/MobileAppProject/Services/FacadeService.cs b/MobileAppProject/Services/FacadeService.cs new file mode 100644 index 0000000..2911516 --- /dev/null +++ b/MobileAppProject/Services/FacadeService.cs @@ -0,0 +1,78 @@ +using MobileAppProject.Interfaces; +using MobileAppProject.Model; +using System.Diagnostics; +using System.Text.Json; +using System.Text; + +namespace MobileAppProject.Services +{ + public class FacadeService : IFacadeService + { + //private readonly IDatabaseService databaseService; + private readonly IGymService gymService; + public FacadeService(IGymService gymService) + { + this.gymService = gymService; + } + + public Task> GetUsers() + { + return gymService.GetUsers(); + } + + public Task CreateUser(User user) + { + return gymService.CreateUser(user); + } + + public Task> GetAllGroups() + { + return gymService.GetAllGroups(); + } + + public Task> GetAllExercises() + { + return gymService.GetAllExercises(); + } + + public Task CreateRoutine(Routine routine) + { + return gymService.CreateRoutine(routine); + } + + public Task> GetRoutinesByUser(int? id) + { + return gymService.GetRoutinesByUser(id); + } + + public Task> GetExercisesByRoutine(int? id) + { + return gymService.GetExercisesByRoutine(id); + } + + public Task AddRoutineExercise(RoutineExercise routineExercise) + { + return gymService.AddRoutineExercise(routineExercise); + } + + public Task UpdateRoutineExercise(int? id, RoutineExercise routineExercise) + { + return gymService.UpdateRoutineExercise(id, routineExercise); + } + + public Task DeleteRoutineExercise(int? id) + { + return gymService.DeleteRoutineExercise(id); + } + + public Task DeleteRoutine(int? id) + { + return gymService.DeleteRoutine(id); + } + + public Task UpdateRoutine(int? id, Routine routine) + { + return gymService.UpdateRoutine(id, routine); + } + } +} diff --git a/MobileAppProject/Services/GymService.cs b/MobileAppProject/Services/GymService.cs new file mode 100644 index 0000000..770488e --- /dev/null +++ b/MobileAppProject/Services/GymService.cs @@ -0,0 +1,316 @@ +using MobileAppProject.Interfaces; +using System.Text.Json; +using System.Threading.Tasks; +using MobileAppProject.Model; +using System.Diagnostics; +using System.Text; +using Microsoft.Maui.Controls; +using System.Text.Json.Serialization; +//using Android.Media; + +namespace MobileAppProject.Services +{ + public class GymService : IGymService + { + HttpClient client; + JsonSerializerOptions serializerOptions; + + public GymService() { + + client= new HttpClient(); + serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; + } + + public async Task> GetUsers() + { + var users = new List(); + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.Users)); + + try + { + HttpResponseMessage response = await client.GetAsync(uri); + if(response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize>(content, serializerOptions); + } + return new List(); + + } catch(Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return new List(); + + } + } + + public async Task CreateUser(User user) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.Users)); + try + { + string json = JsonSerializer.Serialize(user, serializerOptions); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = null; + + response = await client.PostAsync(uri, content); + + if (response.IsSuccessStatusCode) + Debug.WriteLine(@"\tTodoItem successfully saved."); + return true; + + } catch(Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return false; + } + } + + public async Task> GetAllGroups() + { + var users = new List(); + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.MuscleGroups)); + + try + { + HttpResponseMessage response = await client.GetAsync(uri); + if (response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize>(content, serializerOptions); + } + return new List(); + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return new List(); + + } + } + + public async Task> GetAllExercises() + { + var exercises = new List(); + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.Exercises)); + + try + { + HttpResponseMessage response = await client.GetAsync(uri); + if (response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize>(content, serializerOptions); + } + return new List(); + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return new List(); + + } + } + + public async Task CreateRoutine(Routine routine) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.Routines)); + try + { + string json = JsonSerializer.Serialize(routine, serializerOptions); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = null; + + response = await client.PostAsync(uri, content); + + if (response.IsSuccessStatusCode) + Debug.WriteLine(@"\tTodoItem successfully saved."); + return true; + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return false; + } + } + + public async Task> GetRoutinesByUser(int? id) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.Routines,"id?id=",id)); + + try + { + HttpResponseMessage response = await client.GetAsync(uri); + if (response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize>(content, serializerOptions); + } + return new List(); + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return new List(); + + } + } + + public async Task AddRoutineExercise(RoutineExercise routineExercise) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.RoutineExercises)); + try + { + string json = JsonSerializer.Serialize(routineExercise, serializerOptions); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = null; + + response = await client.PostAsync(uri, content); + + if (response.IsSuccessStatusCode) + Debug.WriteLine(@"\tTodoItem successfully saved."); + return true; + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return false; + } + } + + public async Task> GetExercisesByRoutine(int? id) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.RoutineExercises, "id?id=", id)); + + try + { + HttpResponseMessage response = await client.GetAsync(uri); + if (response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize>(content, serializerOptions); + } + return new List(); + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return new List(); + + } + + } + + public async Task UpdateRoutineExercise(int? id, RoutineExercise routineExercise) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.RoutineExercises, "id?id=", id)); + try + { + + RoutineExercise newExercise = new RoutineExercise(); + newExercise.Sets= routineExercise.Sets; + newExercise.Reps= routineExercise.Reps; + newExercise.Weight=routineExercise.Weight; + string json = JsonSerializer.Serialize(newExercise, serializerOptions); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = null; + + response = await client.PutAsync(uri, content); + return true; + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return false; + } + } + + + public async Task DeleteRoutineExercise(int? id) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.RoutineExercises, "id?id=", id)); + + try + { + HttpResponseMessage response = await client.DeleteAsync(uri); + if (response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + } + return true; + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return false; + + } + } + + public async Task DeleteRoutine(int? id) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.Routines, "id?id=", id)); + + try + { + HttpResponseMessage response = await client.DeleteAsync(uri); + if (response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + } + return true; + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return false; + + } + } + + + public async Task UpdateRoutine(int? id, Routine routine) + { + Uri uri = new Uri(string.Concat(Constants.EndpointBase, Constants.Endpoints.Routines, "id?id=", id)); + try + { + + Routine newRoutine = new Routine(); + newRoutine.Name = routine.Name; + newRoutine.Day = routine.Day; + string json = JsonSerializer.Serialize(newRoutine, serializerOptions); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = null; + + response = await client.PutAsync(uri, content); + return true; + + } + catch (Exception ex) + { + Debug.WriteLine(@"\tERROR {0}", ex.Message); + return false; + } + } + + } +} diff --git a/MobileAppProject/Services/PopUpService.cs b/MobileAppProject/Services/PopUpService.cs new file mode 100644 index 0000000..2d3e683 --- /dev/null +++ b/MobileAppProject/Services/PopUpService.cs @@ -0,0 +1,21 @@ +using CommunityToolkit.Maui.Views; +using MobileAppProject.Interfaces; +using MobileAppProject.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +// Code for interface and service from https://stackoverflow.com/questions/75722266/how-to-show-a-popup-from-viewmodel-maui +namespace MobileAppProject.Services +{ + public class PopUpService : IPopUpService + { + public async Task PopUp(Popup popup) + { + Page page = Application.Current?.MainPage ?? throw new NullReferenceException(); + return await page.ShowPopupAsync(popup); + } + } +} diff --git a/MobileAppProject/Services/UserService.cs b/MobileAppProject/Services/UserService.cs new file mode 100644 index 0000000..c774270 --- /dev/null +++ b/MobileAppProject/Services/UserService.cs @@ -0,0 +1,19 @@ +using MobileAppProject.Interfaces; +using MobileAppProject.Model; + +namespace MobileAppProject.Services +{ + class UserService : IUserService + { + public UserService() { } + + + public Task> GetUsers() + { + return Task.FromResult(new List() + { + + }); + } + } +} diff --git a/MobileAppProject/View/CreateRoutineView.xaml b/MobileAppProject/View/CreateRoutineView.xaml new file mode 100644 index 0000000..65f8c2f --- /dev/null +++ b/MobileAppProject/View/CreateRoutineView.xaml @@ -0,0 +1,48 @@ + + + +