diff --git a/AdminPanel.csproj b/AdminPanel.csproj
index d5bc199..030c8ad 100644
--- a/AdminPanel.csproj
+++ b/AdminPanel.csproj
@@ -18,6 +18,9 @@
+
+
+
@@ -27,4 +30,12 @@
+
+
+
+
+
+
+
+
diff --git a/Components/UserComponent.razor b/Components/UserComponent.razor
index b33f1f9..c3562ea 100644
--- a/Components/UserComponent.razor
+++ b/Components/UserComponent.razor
@@ -1,5 +1,4 @@
-
@if (@User.IsAdmin)
{
Administrator @User.Name
@@ -8,6 +7,7 @@
{
@User.Name
}
+
email: @User.Email
id: @User.Id
diff --git a/Models/Team.cs b/Models/Team.cs
new file mode 100644
index 0000000..b4f7f20
--- /dev/null
+++ b/Models/Team.cs
@@ -0,0 +1,6 @@
+namespace AdminPanel.Models;
+
+public record Team(uint Id, string Name, string Picture, string MainColor, string SecondColor)
+{
+
+}
\ No newline at end of file
diff --git a/Pages/DisplayUtils.cs b/Pages/DisplayUtils.cs
new file mode 100644
index 0000000..fd30ce9
--- /dev/null
+++ b/Pages/DisplayUtils.cs
@@ -0,0 +1,24 @@
+using System.Text;
+using AdminPanel.Services;
+using MudBlazor;
+
+namespace AdminPanel.Pages;
+
+public class DisplayUtils
+{
+ public static void ShowErrors(ServiceException e, ISnackbar snackbar)
+ {
+ foreach (var erronedArgument in e.ArgumentMessages)
+ {
+ var sb = new StringBuilder(erronedArgument.Key);
+ sb.Append(" :");
+
+ foreach (var message in erronedArgument.Value)
+ {
+ sb.Append("\n\t-");
+ sb.Append(message);
+ }
+ snackbar.Add(sb.ToString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Pages/TeamListPanel.razor b/Pages/TeamListPanel.razor
index de789a1..813635a 100644
--- a/Pages/TeamListPanel.razor
+++ b/Pages/TeamListPanel.razor
@@ -1,10 +1,106 @@
@page "/teams"
+@using AdminPanel.Models
+@using DataGridEditMode = MudBlazor.DataGridEditMode
Teams Panel
-TeamListPanel
+Team Panel
-@code {
-}
+
+
+
+
+
+
+
+
+ Apply
+
+
+
Close
+
+
+
+
+
+
+
+
+ Add Team
+
+
+
+ Remove selection
+
+
+
+ Teams
+
+
+
+
+
+
+
+
+ Are you sure you want to delete this team(s)?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pages/TeamListPanel.razor.cs b/Pages/TeamListPanel.razor.cs
new file mode 100644
index 0000000..32f2af8
--- /dev/null
+++ b/Pages/TeamListPanel.razor.cs
@@ -0,0 +1,109 @@
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+using AdminPanel.Models;
+using AdminPanel.Services;
+using Blazorise.Extensions;
+using Microsoft.AspNetCore.Components;
+using MudBlazor;
+
+namespace AdminPanel.Pages;
+
+public partial class TeamListPanel
+{
+ [Inject] private ISnackbar Snackbar { get; init; }
+ [Inject] private ITeamService TeamService { get; init; }
+ private bool _isOpenAdd;
+ private bool _isOpenConf;
+ private bool _success;
+ private string[] _errors = { };
+
+ [StringLength(1,ErrorMessage = "Nombre de caractères minimal : 1 ")]
+ private string? FormName { get; set; }
+
+ [RegularExpression(@"(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})?", ErrorMessage = "L'image doit être le lien d'une image sur le web")]
+ private string? FormPicture { get; set; }
+
+ [RegularExpression(@"(/#[0-9a-f]{6})",ErrorMessage = "La couleur principale doit être un code hexadécimal")]
+ private string? FormMainColor { get; set; }
+
+ [RegularExpression(@"(/#[0-9a-f]{6})",ErrorMessage = "La couleur secondaire doit être un code hexadécimal")]
+ private string? FormSecondaryColor { get; set; }
+ private MudDataGrid? Grid { get; set; }
+ private HashSet SelectedTeams { get; set; } = new();
+
+ private void UnBindForm()
+ {
+ FormName = null;
+ FormPicture = null;
+ FormMainColor = null;
+ FormSecondaryColor = null;
+ }
+
+ private async Task> GetTeamsFromServer(GridState state)
+ {
+ var (count, teams) = await TeamService.ListTeam((uint)(state.Page * state.PageSize), (uint)state.PageSize);
+ return new GridData
+ {
+ TotalItems = (int)count,
+ Items = teams
+ };
+ }
+
+ private void ToggleOpen()
+ {
+ _isOpenAdd = !(_isOpenAdd);
+ }
+
+ private void ToggleOpenConfirmation()
+ {
+ _isOpenConf = !(_isOpenConf);
+ }
+
+ private async Task AddTeam()
+ {
+ try
+ {
+ await TeamService.AddTeam(FormName!, FormPicture!, FormMainColor!, FormSecondaryColor!);
+ }
+ catch (ServiceException err)
+ {
+ DisplayUtils.ShowErrors(err,Snackbar);
+ }
+ }
+
+ private async void AddTeamConfirmed()
+ {
+ await AddTeam();
+ ToggleOpen();
+ await Grid!.ReloadServerData();
+ UnBindForm();
+ }
+
+ private async void DeleteSelectedTeams()
+ {
+ if (!SelectedTeams.IsNullOrEmpty())
+ {
+ var ids = SelectedTeams.ToList().ConvertAll(team => team.Id);
+ await TeamService.DeleteTeams(ids);
+ await Grid!.ReloadServerData();
+ }
+ CloseToggleConf();
+ }
+
+ private void CloseToggleConf()
+ {
+ _isOpenConf = false;
+ }
+
+ private async void OnTeamUpdated(Team t)
+ {
+ try
+ {
+ await TeamService.UpdateTeam(t);
+ }
+ catch (ServiceException err)
+ {
+ DisplayUtils.ShowErrors(err,Snackbar);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Pages/UserListPanel.razor.cs b/Pages/UserListPanel.razor.cs
index f4eff47..3b3d51d 100644
--- a/Pages/UserListPanel.razor.cs
+++ b/Pages/UserListPanel.razor.cs
@@ -52,7 +52,7 @@ namespace AdminPanel.Pages
}
catch (ServiceException err)
{
- ShowErrors(err);
+ DisplayUtils.ShowErrors(err,Snackbar);
}
}
@@ -70,25 +70,10 @@ namespace AdminPanel.Pages
}
catch (ServiceException err)
{
- ShowErrors(err);
- }
- }
-
- private void ShowErrors(ServiceException e)
- {
- foreach (var erronedArgument in e.ArgumentMessages)
- {
- var sb = new StringBuilder(erronedArgument.Key);
- sb.Append(" :");
-
- foreach (var message in erronedArgument.Value)
- {
- sb.Append("\n\t-");
- sb.Append(message);
- }
- Snackbar.Add(sb.ToString());
+ DisplayUtils.ShowErrors(err,Snackbar);
}
}
+
private async void RemoveSelection(MouseEventArgs e)
{
@@ -101,7 +86,7 @@ namespace AdminPanel.Pages
}
catch (ServiceException err)
{
- ShowErrors(err);
+ DisplayUtils.ShowErrors(err,Snackbar);
}
}
diff --git a/Program.cs b/Program.cs
index 91dd8e2..ae3bdd6 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,5 +1,4 @@
using AdminPanel;
-using AdminPanel.Pages;
using AdminPanel.Services;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
@@ -8,7 +7,6 @@ using MudBlazor.Services;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("#app");
builder.RootComponents.Add("head::after");
-
builder.Services
.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
@@ -21,8 +19,10 @@ var client = new HttpClient
builder.Services.AddScoped(sp => new HttpUsersService(client));
//builder.Services.AddScoped();
+builder.Services.AddScoped(sp => new HttpTeamService(client));
builder.Services.AddMudServices();
-await builder.Build().RunAsync();
\ No newline at end of file
+await builder.Build().RunAsync();
+
diff --git a/Services/ErrorsUtils.cs b/Services/ErrorsUtils.cs
new file mode 100644
index 0000000..62c3e8c
--- /dev/null
+++ b/Services/ErrorsUtils.cs
@@ -0,0 +1,27 @@
+using System.Net;
+using System.Net.Http.Json;
+
+namespace AdminPanel.Services;
+
+public class ErrorsUtils
+{
+ private record ServerErrorMessageDto(string? Field, string? Error, string Message);
+
+ public static async Task EnsureResponseIsOk(HttpResponseMessage response)
+ {
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ return;
+ }
+
+ var content = await response.Content.ReadFromJsonAsync();
+ var messages = content!
+ .GroupBy(e => e.Field ?? e.Error!)
+ .ToDictionary(
+ g => g.Key,
+ g => g.ToList().ConvertAll(e => e.Message)
+ );
+
+ throw new ServiceException("Server refused request", messages);
+ }
+}
\ No newline at end of file
diff --git a/Services/HttpTeamService.cs b/Services/HttpTeamService.cs
new file mode 100644
index 0000000..6f38f26
--- /dev/null
+++ b/Services/HttpTeamService.cs
@@ -0,0 +1,50 @@
+using System.Net.Http.Json;
+using AdminPanel.Models;
+
+namespace AdminPanel.Services;
+
+public class HttpTeamService : ITeamService
+{
+
+ private readonly HttpClient _client;
+
+ public HttpTeamService(HttpClient client)
+ {
+ this._client = client;
+ }
+
+ private record ListTeamResponse(uint TotalCount, List Teams);
+
+ public async Task<(uint, List)> ListTeam(uint from, uint count)
+ {
+ var httpResponse = await _client.GetAsync($"/api/admin/list-team?start={from}&n={count}");
+ httpResponse.EnsureSuccessStatusCode();
+ var response = await httpResponse.Content.ReadFromJsonAsync()!;
+
+ return (response.TotalCount, response.Teams);
+ }
+
+ private record AddTeamDTORequest(string Name, string Picture, string MainColor, string SecondaryColor);
+
+ public async Task AddTeam(string name, string picture, string mainColor, string secondaryColor)
+ {
+ var httpResponse = await _client.PostAsJsonAsync($"/api/admin/add-team", new AddTeamDTORequest(name,picture,mainColor,secondaryColor));
+ await ErrorsUtils.EnsureResponseIsOk(httpResponse);
+ }
+
+ private record DeleteTeamsDTORequest(List Teams);
+ public async Task DeleteTeams(List teams)
+ {
+ var httpResponse = await _client.PostAsJsonAsync($"/api/admin/delete-teams", new DeleteTeamsDTORequest(teams));
+ await ErrorsUtils.EnsureResponseIsOk(httpResponse);
+
+ }
+
+ private record UpdateTeamDTORequest(uint Id, string Name, string Picture, string MainColor, string SecondaryColor);
+ public async Task UpdateTeam(Team team)
+ {
+ var httpResponse = await _client.PostAsJsonAsync($"/api/admin/team/{team.Id}/update",
+ new UpdateTeamDTORequest(team.Id, team.Name, team.Picture, team.MainColor, team.SecondColor) );
+ await ErrorsUtils.EnsureResponseIsOk(httpResponse);
+ }
+}
\ No newline at end of file
diff --git a/Services/HttpUsersService.cs b/Services/HttpUsersService.cs
index 824fefd..3582edc 100644
--- a/Services/HttpUsersService.cs
+++ b/Services/HttpUsersService.cs
@@ -13,35 +13,14 @@ public class HttpUsersService : IUsersService
{
this.Client = client;
}
-
- private record ServerErrorMessageDto(string? Field, string? Error, string Message);
-
- private async Task EnsureResponseIsOk(HttpResponseMessage response)
- {
-
- if (response.StatusCode == HttpStatusCode.OK)
- {
- return;
- }
-
- var content = await response.Content.ReadFromJsonAsync();
- var messages = content!
- .GroupBy(e => e.Field ?? e.Error!)
- .ToDictionary(
- g => g.Key,
- g => g.ToList().ConvertAll(e => e.Message)
- );
-
- throw new ServiceException("Server refused request", messages);
- }
-
+
private record ListUsersResponseDto(List Users, uint TotalCount);
public async Task<(uint, List)> ListUsers(uint from, uint len, string? searchString = null)
{
var httpResponse =
await Client.GetAsync($"/api/admin/list-users?start={from}&n={len}&search={searchString ?? ""}");
- await EnsureResponseIsOk(httpResponse);
+ await ErrorsUtils.EnsureResponseIsOk(httpResponse);
var response = await httpResponse.Content.ReadFromJsonAsync()
?? throw new Exception("Received non-parseable json from server");
@@ -58,7 +37,7 @@ public class HttpUsersService : IUsersService
var httpResponse = await Client.PostAsJsonAsync("/api/admin/user/add",
new AddUserRequestDto(username, email, password, isAdmin));
- await EnsureResponseIsOk(httpResponse);
+ await ErrorsUtils.EnsureResponseIsOk(httpResponse);
var response = await httpResponse.Content.ReadFromJsonAsync()
?? throw new Exception("Received non-parseable json from server");
@@ -79,7 +58,7 @@ public class HttpUsersService : IUsersService
var httpResponse =
await Client.PostAsJsonAsync("/api/admin/user/remove-all", new RemoveUsersRequestDto(userIds.ToArray()));
- await EnsureResponseIsOk(httpResponse);
+ await ErrorsUtils.EnsureResponseIsOk(httpResponse);
}
private record UpdateUserRequestDto(string Email, string Username, bool IsAdmin);
@@ -88,6 +67,6 @@ public class HttpUsersService : IUsersService
{
var httpResponse = await Client.PostAsJsonAsync($"/api/admin/user/{user.Id}/update",
new UpdateUserRequestDto(user.Email, user.Name, user.IsAdmin));
- await EnsureResponseIsOk(httpResponse);
+ await ErrorsUtils.EnsureResponseIsOk(httpResponse);
}
}
\ No newline at end of file
diff --git a/Services/ITeamService.cs b/Services/ITeamService.cs
new file mode 100644
index 0000000..163d883
--- /dev/null
+++ b/Services/ITeamService.cs
@@ -0,0 +1,12 @@
+using AdminPanel.Models;
+
+namespace AdminPanel.Services;
+
+public interface ITeamService
+{
+ public Task<(uint, List)> ListTeam(uint from, uint count);
+ public Task AddTeam(string name, string picture, string mainColor, string secondaryColor);
+ public Task DeleteTeams(List teams);
+ public Task UpdateTeam(Team team);
+
+}
\ No newline at end of file
diff --git a/Services/ServiceException.cs b/Services/ServiceException.cs
index 8dbcb00..853efac 100644
--- a/Services/ServiceException.cs
+++ b/Services/ServiceException.cs
@@ -1,6 +1,9 @@
+using System.Net;
+using System.Net.Http.Json;
+
namespace AdminPanel.Services;
-class ServiceException : Exception
+public class ServiceException : Exception
{
public Dictionary> ArgumentMessages { get; init; }
@@ -15,4 +18,6 @@ class ServiceException : Exception
{
ArgumentMessages = arguments;
}
+
+
}
\ No newline at end of file
diff --git a/Shared/NavMenu.razor b/Shared/NavMenu.razor
index 51db3dd..fedc92f 100644
--- a/Shared/NavMenu.razor
+++ b/Shared/NavMenu.razor
@@ -15,8 +15,13 @@
-
- Users
+
+ Users
+
+
+
+
+ Teams
diff --git a/wwwroot/index.html b/wwwroot/index.html
index 74fb073..7d18a24 100644
--- a/wwwroot/index.html
+++ b/wwwroot/index.html
@@ -16,6 +16,7 @@
+