From 33c631aaf67141968cc89ff9ffcb0f2e9d7c6d87 Mon Sep 17 00:00:00 2001 From: Andre Beging Date: Mon, 24 Jan 2022 10:15:33 +0100 Subject: [PATCH] Users page and users service --- FoodsharingSiegen.Contracts/Entity/dfg.cs | 7 - .../OperationResult.cs | 138 ++++++++++++++++++ .../Data/Service/ServiceBase.cs | 21 +++ .../Data/Service/UserService.cs | 73 +++++++++ FoodsharingSiegen.Server/Pages/Index.razor | 9 -- FoodsharingSiegen.Server/Pages/Users.razor | 72 +++++++++ FoodsharingSiegen.Server/Pages/Users.razor.cs | 56 +++++++ FoodsharingSiegen.Server/Program.cs | 15 +- FoodsharingSiegen.Server/Shared/NavMenu.razor | 13 +- .../Shared/NavMenu.razor.css | 6 +- 10 files changed, 380 insertions(+), 30 deletions(-) delete mode 100644 FoodsharingSiegen.Contracts/Entity/dfg.cs create mode 100644 FoodsharingSiegen.Contracts/OperationResult.cs create mode 100644 FoodsharingSiegen.Server/Data/Service/ServiceBase.cs create mode 100644 FoodsharingSiegen.Server/Data/Service/UserService.cs delete mode 100644 FoodsharingSiegen.Server/Pages/Index.razor create mode 100644 FoodsharingSiegen.Server/Pages/Users.razor create mode 100644 FoodsharingSiegen.Server/Pages/Users.razor.cs diff --git a/FoodsharingSiegen.Contracts/Entity/dfg.cs b/FoodsharingSiegen.Contracts/Entity/dfg.cs deleted file mode 100644 index 79a9271..0000000 --- a/FoodsharingSiegen.Contracts/Entity/dfg.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace FoodsharingSiegen.Contracts.Entity -{ - public class dfg - { - - } -} \ No newline at end of file diff --git a/FoodsharingSiegen.Contracts/OperationResult.cs b/FoodsharingSiegen.Contracts/OperationResult.cs new file mode 100644 index 0000000..84085de --- /dev/null +++ b/FoodsharingSiegen.Contracts/OperationResult.cs @@ -0,0 +1,138 @@ +namespace FoodsharingSiegen.Contracts +{ + #region OperationResult + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Encapsulates the result of an operation. + /// + /// A Beging, 20.10.2021. + /// + /// Generic type parameter. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public class OperationResult + { + #region Public Properties + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Gets or sets the exception. + /// + /// The exception. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public Exception? Exception { get; set; } + + /// Returns an error message if the exception is set + public string ErrorMessage + { + get + { + if (Success) return string.Empty; + return Exception != null ? Exception.GetBaseException().Message : "Fehler"; + } + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Gets or sets a value indicating whether the success. + /// + /// True if success, false if not. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public bool Success { get; set; } = true; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Gets or sets the data. + /// + /// The data. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public T? Data { get; set; } + + #endregion Public Properties + + #region Constructors + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Constructor. + /// + /// A Beging, 20.10.2021. + /// + /// The exception. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public OperationResult(Exception exception) + { + Success = false; + Exception = exception; + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Constructor. + /// + /// A Beging, 20.10.2021. + /// + /// The data. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public OperationResult(T data) + { + Data = data; + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Default constructor. + /// + /// A Beging, 22.10.2021. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public OperationResult() + { + + } + + #endregion Constructors + } + + #endregion OperationResult + + #region OperationResult + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Encapsulates the result of an operation. + /// + /// A Beging, 20.10.2021. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public class OperationResult : OperationResult + { + #region Constructors + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Constructor. + /// + /// A Beging, 20.10.2021. + /// + /// The exception. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public OperationResult(Exception exception) : base(exception) + { + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Constructor. + /// + /// A Beging, 20.10.2021. + /// + /// True to data. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public OperationResult(bool data) : base(data) + { + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Default constructor. + /// + /// A Beging, 22.10.2021. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public OperationResult() + { + + } + + #endregion Constructors + } + + #endregion OperationResult +} \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Data/Service/ServiceBase.cs b/FoodsharingSiegen.Server/Data/Service/ServiceBase.cs new file mode 100644 index 0000000..4af4a00 --- /dev/null +++ b/FoodsharingSiegen.Server/Data/Service/ServiceBase.cs @@ -0,0 +1,21 @@ +namespace FoodsharingSiegen.Server.Data.Service +{ + public class ServiceBase + { + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Database Context + /// + /// The context. + //////////////////////////////////////////////////////////////////////////////////////////////////// + protected FsContext Context { get; } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Specialised constructor for use only by derived class. + /// + /// A Beging, 20.10.2021. + /// + /// The context. + //////////////////////////////////////////////////////////////////////////////////////////////////// + protected ServiceBase(FsContext context) => Context = context; + } +} \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Data/Service/UserService.cs b/FoodsharingSiegen.Server/Data/Service/UserService.cs new file mode 100644 index 0000000..9f8c9d8 --- /dev/null +++ b/FoodsharingSiegen.Server/Data/Service/UserService.cs @@ -0,0 +1,73 @@ +using FoodsharingSiegen.Contracts; +using FoodsharingSiegen.Contracts.Entity; +using Microsoft.EntityFrameworkCore; + +namespace FoodsharingSiegen.Server.Data.Service +{ + public class UserService : ServiceBase + { + public UserService(FsContext context) : base(context) + { + + } + + public async Task> AddUserAsync(User user) + { + try + { + if (await Context.Users.AnyAsync(x => x.Mail.ToLower().Equals(user.Mail.ToLower()))) + return new OperationResult(new Exception("Diese E-Mail Adresse wird bereits verwendet")); + + user.Created = DateTime.UtcNow; + + await Context.Users.AddAsync(user); + + var saveResult = await Context.SaveChangesAsync(); + if (saveResult == 0) return new OperationResult(new Exception("Fehler bei der Registrierung")); + + return new OperationResult(user); + } + catch (Exception e) + { + return new OperationResult(e); + } + + } + + public async Task Update(User user) + { + try + { + Context.Users.Update(user); + var saveR = await Context.SaveChangesAsync(); + + if(saveR < 1) return new OperationResult(new Exception("Fehler beim speichern")); + return new OperationResult(); + } + catch (Exception e) + { + return new OperationResult(e); + } + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Gets users asynchronous. + /// + /// A Beging, 20.10.2021. + /// + /// An asynchronous result that yields the users. + //////////////////////////////////////////////////////////////////////////////////////////////////// + public async Task>> GetUsersAsync() + { + try + { + var users = await Context.Users.ToListAsync(); + return new OperationResult>(users); + } + catch (Exception e) + { + return new OperationResult>(e); + } + } + } +} \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Pages/Index.razor b/FoodsharingSiegen.Server/Pages/Index.razor deleted file mode 100644 index d1c2757..0000000 --- a/FoodsharingSiegen.Server/Pages/Index.razor +++ /dev/null @@ -1,9 +0,0 @@ -@page "/" - -Index - -

Hello, world!

- -Welcome to your new app. - - \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Pages/Users.razor b/FoodsharingSiegen.Server/Pages/Users.razor new file mode 100644 index 0000000..0bb7604 --- /dev/null +++ b/FoodsharingSiegen.Server/Pages/Users.razor @@ -0,0 +1,72 @@ +@page "/" +@using FoodsharingSiegen.Contracts.Entity + +@code { + + private RenderFragment PopupTitleTemplate(PopupTitleContext value) + { + var header = "Benutzer erstellen"; + if (value.EditState == DataGridEditState.Edit) header = "Benutzer bearbeiten"; + + return builder => + { + builder.OpenElement(0, "span"); + builder.AddContent(1, header); + builder.CloseElement(); + }; + } + +} + +Benutzer + +

Benutzerverwaltung Admin

+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Pages/Users.razor.cs b/FoodsharingSiegen.Server/Pages/Users.razor.cs new file mode 100644 index 0000000..5761ccf --- /dev/null +++ b/FoodsharingSiegen.Server/Pages/Users.razor.cs @@ -0,0 +1,56 @@ +using Blazorise.DataGrid; +using FoodsharingSiegen.Contracts.Entity; +using FoodsharingSiegen.Server.Data.Service; +using Microsoft.AspNetCore.Components; + +namespace FoodsharingSiegen.Server.Pages +{ + public partial class Users + { + //////////////////////////////////////////////////////////////////////////////////////////////////// + /// Gets or sets the user service. + /// + /// The user service. + //////////////////////////////////////////////////////////////////////////////////////////////////// + [Inject] public UserService UserService { get; set; } = null!; + + private List? UserList { get; set; } + public DataGrid UserDataGrid { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await LoadUsers(); + + await base.OnAfterRenderAsync(firstRender); + } + + private async Task LoadUsers() + { + var usersR = await UserService.GetUsersAsync(); + if (usersR.Success) UserList = usersR.Data; + + await InvokeAsync(StateHasChanged); + } + + private async Task RowUpdated(SavedRowItem> arg) + { + if (arg.Item?.Id == null || arg.Item.Id.Equals(Guid.Empty) || arg.Values?.Any() != true) return; + + await UserService.Update(arg.Item); + } + + private async Task RowInserted(SavedRowItem> arg) + { + var addUserR = await UserService.AddUserAsync(arg.Item); + if (!addUserR.Success) + { + // Error Toast + } + else + { + await LoadUsers(); + } + } + } +} \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Program.cs b/FoodsharingSiegen.Server/Program.cs index be80b5f..39efe40 100644 --- a/FoodsharingSiegen.Server/Program.cs +++ b/FoodsharingSiegen.Server/Program.cs @@ -1,6 +1,9 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; +using Blazorise; +using Blazorise.Icons.Material; +using Blazorise.Material; using FoodsharingSiegen.Server.Data; +using FoodsharingSiegen.Server.Data.Service; +using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); @@ -8,6 +11,14 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddSingleton(); +builder.Services.AddDbContextFactory(opt => + opt.UseSqlite($"Data Source=app.db")); + +// DI +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +builder.Services.AddBlazorise(options => { options.ChangeTextOnKeyPress = true; }).AddMaterialProviders().AddMaterialIcons(); var app = builder.Build(); diff --git a/FoodsharingSiegen.Server/Shared/NavMenu.razor b/FoodsharingSiegen.Server/Shared/NavMenu.razor index a24a2f5..bbab352 100644 --- a/FoodsharingSiegen.Server/Shared/NavMenu.razor +++ b/FoodsharingSiegen.Server/Shared/NavMenu.razor @@ -1,6 +1,6 @@