Run code clean and fix messages
All checks were successful
Game Ideas build for PR / build_test (pull_request) Successful in 1m26s
All checks were successful
Game Ideas build for PR / build_test (pull_request) Successful in 1m26s
This commit is contained in:
@@ -13,7 +13,7 @@ public static class GameHelper
|
|||||||
throw new ArgumentNullException(nameof(authState), "Authentication state missing");
|
throw new ArgumentNullException(nameof(authState), "Authentication state missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
var userId = authState.User.FindFirstValue(ClaimTypes.Sid)
|
var userId = authState.User.FindFirstValue(ClaimTypes.Sid)
|
||||||
?? throw new ArgumentNullException(nameof(authState), "user state missing");
|
?? throw new ArgumentNullException(nameof(authState), "user state missing");
|
||||||
|
|
||||||
game.CreationUserId = userId;
|
game.CreationUserId = userId;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Components;
|
|||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Microsoft.AspNetCore.Components.Forms;
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using System.Security.Claims;
|
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Pages.Games.Components;
|
namespace GameIdeas.BlazorApp.Pages.Games.Components;
|
||||||
|
|
||||||
@@ -21,7 +20,7 @@ public partial class GameCreationForm
|
|||||||
[Parameter] public CategoriesDto? Categories { get; set; }
|
[Parameter] public CategoriesDto? Categories { get; set; }
|
||||||
[Parameter] public EventCallback OnSubmit { get; set; }
|
[Parameter] public EventCallback OnSubmit { get; set; }
|
||||||
|
|
||||||
private GameDetailDto GameDto = new();
|
private readonly GameDetailDto GameDto = new();
|
||||||
private EditContext? EditContext;
|
private EditContext? EditContext;
|
||||||
private readonly SelectTheme Theme = SelectTheme.Creation;
|
private readonly SelectTheme Theme = SelectTheme.Creation;
|
||||||
private readonly SliderParams SliderParams = new() { Gap = 1, Min = 1, Max = 5 };
|
private readonly SliderParams SliderParams = new() { Gap = 1, Min = 1, Max = 5 };
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
@inherits GameBase
|
@inherits GameBase
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<img class="icon" src="~/icon.png" />
|
<img class="icon" src="icon.png" />
|
||||||
|
|
||||||
<a class="title" href="@($"/Detail/{GameDto.Id}")">@GameDto.Title</a>
|
<a class="title" href="@($"/Detail/{GameDto.Id}")">@GameDto.Title</a>
|
||||||
|
|
||||||
|
|||||||
@@ -80,9 +80,20 @@
|
|||||||
fill: var(--white);
|
fill: var(--white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px) {
|
||||||
|
.release-date {
|
||||||
|
display: none;
|
||||||
|
grid-column: span;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
grid-template-columns: auto 3fr 3fr 30px 30px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1000px) {
|
@media screen and (max-width: 1000px) {
|
||||||
.row {
|
.row {
|
||||||
grid-template-columns: 48px 3fr 2fr 3fr 30px 30px;
|
grid-template-columns: auto 3fr 2fr 3fr 30px 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags, .storage {
|
.tags, .storage {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public partial class Games
|
|||||||
GameFilter.SortType = Filter.GameFilter.SortTypes
|
GameFilter.SortType = Filter.GameFilter.SortTypes
|
||||||
.First(st => st.SortType == SortType.Ascending);
|
.First(st => st.SortType == SortType.Ascending);
|
||||||
|
|
||||||
GameFilter.SortProperty= Filter.GameFilter.GameProperties
|
GameFilter.SortProperty = Filter.GameFilter.GameProperties
|
||||||
.First(gp => gp.PropertyName == nameof(GameIdeas.Shared.Model.Game.Title));
|
.First(gp => gp.PropertyName == nameof(GameIdeas.Shared.Model.Game.Title));
|
||||||
|
|
||||||
await HandleFetchDatas();
|
await HandleFetchDatas();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class GameGateway(IHttpClientService httpClientService) : IGameGateway
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await httpClientService.FetchDataAsync<CategoriesDto>(Endpoints.Category.AllCategories);
|
var result = await httpClientService.FetchDataAsync<CategoriesDto>(Endpoints.Category.AllCategories);
|
||||||
|
|
||||||
return result ?? throw new InvalidOperationException(ResourcesKey.ErrorFetchCategories);
|
return result ?? throw new InvalidOperationException(ResourcesKey.ErrorFetchCategories);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ public partial class Login
|
|||||||
[Parameter] public IAuthGateway AuthGateway { get; set; } = default!;
|
[Parameter] public IAuthGateway AuthGateway { get; set; } = default!;
|
||||||
|
|
||||||
private EditContext? EditContext;
|
private EditContext? EditContext;
|
||||||
private UserDto UserDto = new();
|
private readonly UserDto UserDto = new();
|
||||||
private bool IsLoading = false;
|
private bool IsLoading = false;
|
||||||
private LoginValidator Validator = new();
|
private readonly LoginValidator Validator = new();
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
EditContext = new EditContext(UserDto);
|
EditContext = new EditContext(UserDto);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Select;
|
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||||
using GameIdeas.Shared.Dto;
|
using GameIdeas.Shared.Dto;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|||||||
@@ -37,36 +37,36 @@ public class UserGateway(IHttpClientService httpClient) : IUserGateway
|
|||||||
|
|
||||||
public async Task<IEnumerable<RoleDto>> GetRoles()
|
public async Task<IEnumerable<RoleDto>> GetRoles()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await httpClient.FetchDataAsync<IEnumerable<RoleDto>>(Endpoints.User.Roles)
|
return await httpClient.FetchDataAsync<IEnumerable<RoleDto>>(Endpoints.User.Roles)
|
||||||
?? throw new InvalidOperationException(ResourcesKey.ErrorFetchRoles);
|
?? throw new InvalidOperationException(ResourcesKey.ErrorFetchRoles);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
throw new RoleNotFoundException(ResourcesKey.ErrorFetchRoles);
|
throw new RoleNotFoundException(ResourcesKey.ErrorFetchRoles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserListDto> GetUsers(UserFilterParams filterParams, int currentPage)
|
public async Task<UserListDto> GetUsers(UserFilterParams filterParams, int currentPage)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UserFilterDto filter = new()
|
UserFilterDto filter = new()
|
||||||
{
|
{
|
||||||
CurrentPage = currentPage,
|
CurrentPage = currentPage,
|
||||||
Name = filterParams.Name,
|
Name = filterParams.Name,
|
||||||
RoleIds = filterParams.Roles?.Select(r => r.Id)
|
RoleIds = filterParams.Roles?.Select(r => r.Id)
|
||||||
};
|
};
|
||||||
|
|
||||||
var url = Endpoints.User.Fetch(filter);
|
var url = Endpoints.User.Fetch(filter);
|
||||||
return await httpClient.FetchDataAsync<UserListDto>(url)
|
return await httpClient.FetchDataAsync<UserListDto>(url)
|
||||||
?? throw new InvalidOperationException(ResourcesKey.ErrorFetchUsers);
|
?? throw new InvalidOperationException(ResourcesKey.ErrorFetchUsers);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
throw new UserNotFoundException(ResourcesKey.ErrorFetchUsers);
|
throw new UserNotFoundException(ResourcesKey.ErrorFetchUsers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IdDto> UpdateUser(UserDto user)
|
public async Task<IdDto> UpdateUser(UserDto user)
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ public partial class Users
|
|||||||
|
|
||||||
private Popup? Popup;
|
private Popup? Popup;
|
||||||
private bool IsLoading = false;
|
private bool IsLoading = false;
|
||||||
private UserFilterParams FilterParams = new();
|
private readonly UserFilterParams FilterParams = new();
|
||||||
private UserListDto UserList = new();
|
private UserListDto UserList = new();
|
||||||
private IEnumerable<RoleDto> Roles = [];
|
private IEnumerable<RoleDto> Roles = [];
|
||||||
private int CurrentPage = 1;
|
private readonly int CurrentPage = 1;
|
||||||
private UserDto UserAdd = new();
|
private UserDto UserAdd = new();
|
||||||
private UserDto? UserDelete;
|
private UserDto? UserDelete;
|
||||||
private string? currentUserId;
|
private string? currentUserId;
|
||||||
@@ -34,7 +34,7 @@ public partial class Users
|
|||||||
NavigationManager.NavigateTo("/Unauthorized");
|
NavigationManager.NavigateTo("/Unauthorized");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
await FetchData();
|
await FetchData();
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
@@ -57,7 +57,7 @@ public partial class Users
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
IsLoading = false;
|
IsLoading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Net.Http.Json;
|
|
||||||
using Blazored.LocalStorage;
|
using Blazored.LocalStorage;
|
||||||
using GameIdeas.BlazorApp;
|
using GameIdeas.BlazorApp;
|
||||||
using GameIdeas.BlazorApp.Pages.Games.Gateways;
|
using GameIdeas.BlazorApp.Pages.Games.Gateways;
|
||||||
@@ -10,6 +9,7 @@ using GameIdeas.Shared.Constants;
|
|||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Microsoft.AspNetCore.Components.Web;
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
|
||||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||||
var services = builder.Services;
|
var services = builder.Services;
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
using GameIdeas.Resources;
|
using Blazored.LocalStorage;
|
||||||
using System.Net.Http.Headers;
|
using GameIdeas.Resources;
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text;
|
|
||||||
using Blazored.LocalStorage;
|
|
||||||
using GameIdeas.Shared.Constants;
|
using GameIdeas.Shared.Constants;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Services;
|
namespace GameIdeas.BlazorApp.Services;
|
||||||
|
|
||||||
public class HttpClientService(
|
public class HttpClientService(
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
ILocalStorageService localStorage,
|
ILocalStorageService localStorage,
|
||||||
AuthenticationStateProvider stateProvider) : IHttpClientService
|
AuthenticationStateProvider stateProvider) : IHttpClientService
|
||||||
{
|
{
|
||||||
private readonly HttpClient httpClient = httpClientFactory.CreateClient("GameIdeas.WebAPI");
|
private readonly HttpClient httpClient = httpClientFactory.CreateClient("GameIdeas.WebAPI");
|
||||||
private readonly ILogger<HttpClientService> logger = loggerFactory.CreateLogger<HttpClientService>();
|
private readonly ILogger<HttpClientService> logger = loggerFactory.CreateLogger<HttpClientService>();
|
||||||
|
|
||||||
private readonly JsonSerializerOptions _optionsCamelCase = new()
|
private readonly JsonSerializerOptions _optionsCamelCase = new()
|
||||||
{
|
{
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
@@ -145,8 +145,8 @@ public class HttpClientService(
|
|||||||
{
|
{
|
||||||
var expired = await localStorage.GetItemAsStringAsync(GlobalConstants.LS_EXPIRED_STORAGE_KEY);
|
var expired = await localStorage.GetItemAsStringAsync(GlobalConstants.LS_EXPIRED_STORAGE_KEY);
|
||||||
|
|
||||||
if (expired == null
|
if (expired == null
|
||||||
|| (DateTime.TryParse(expired, out DateTime expiration)
|
|| (DateTime.TryParse(expired, out DateTime expiration)
|
||||||
&& expiration < DateTime.UtcNow))
|
&& expiration < DateTime.UtcNow))
|
||||||
{
|
{
|
||||||
await ((JwtAuthenticationStateProvider)stateProvider).NotifyUserLogoutAsync();
|
await ((JwtAuthenticationStateProvider)stateProvider).NotifyUserLogoutAsync();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using Blazored.LocalStorage;
|
using Blazored.LocalStorage;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
|
||||||
using GameIdeas.Shared.Constants;
|
using GameIdeas.Shared.Constants;
|
||||||
using GameIdeas.Shared.Dto;
|
using GameIdeas.Shared.Dto;
|
||||||
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Services;
|
namespace GameIdeas.BlazorApp.Services;
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ public class JwtAuthenticationStateProvider(ILocalStorageService localStorage) :
|
|||||||
{
|
{
|
||||||
var savedToken = await localStorage.GetItemAsStringAsync(GlobalConstants.LS_AUTH_STORAGE_KEY);
|
var savedToken = await localStorage.GetItemAsStringAsync(GlobalConstants.LS_AUTH_STORAGE_KEY);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(savedToken))
|
if (!string.IsNullOrWhiteSpace(savedToken))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await Js.InvokeVoidAsync("setBodyOverflow", "auto");
|
await Js.InvokeVoidAsync("setBodyOverflow", "visible");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Select;
|
using GameIdeas.BlazorApp.Shared.Components.Select;
|
||||||
|
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||||
using GameIdeas.BlazorApp.Shared.Models;
|
using GameIdeas.BlazorApp.Shared.Models;
|
||||||
using GameIdeas.Resources;
|
using GameIdeas.Resources;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
using GameIdeas.BlazorApp.Shared.Components.Select;
|
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
|
||||||
using GameIdeas.BlazorApp.Shared.Models;
|
|
||||||
using GameIdeas.Resources;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Shared.Components.Header;
|
namespace GameIdeas.BlazorApp.Shared.Components.Header;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Shared.Components.ReadMore;
|
namespace GameIdeas.BlazorApp.Shared.Components.ReadMore;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||||
using GameIdeas.Resources;
|
|
||||||
using GameIdeas.Shared.Constants;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Components.Forms;
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Shared.Components.Select;
|
namespace GameIdeas.BlazorApp.Shared.Components.Select;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using GameIdeas.BlazorApp.Shared.Components.Search;
|
using GameIdeas.BlazorApp.Shared.Components.Search;
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Select;
|
using GameIdeas.BlazorApp.Shared.Components.Select;
|
||||||
|
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Shared.Components.SelectSearch;
|
namespace GameIdeas.BlazorApp.Shared.Components.SelectSearch;
|
||||||
@@ -34,15 +34,15 @@ public partial class SelectSearch<TItem>
|
|||||||
}
|
}
|
||||||
private async Task HandleValuesChanged(IEnumerable<TItem> values)
|
private async Task HandleValuesChanged(IEnumerable<TItem> values)
|
||||||
{
|
{
|
||||||
Values = values.ToList();
|
Values = [.. values];
|
||||||
SearchInput?.SetText(string.Join(", ", Values.Select(GetLabel)));
|
SearchInput?.SetText(string.Join(", ", Values.Select(GetLabel)));
|
||||||
await ValuesChanged.InvokeAsync(Values.ToList());
|
await ValuesChanged.InvokeAsync([.. Values]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleClearClicked()
|
private async Task HandleClearClicked()
|
||||||
{
|
{
|
||||||
Values = [];
|
Values = [];
|
||||||
await ValuesChanged.InvokeAsync(Values.ToList());
|
await ValuesChanged.InvokeAsync([.. Values]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleFocusIn()
|
private void HandleFocusIn()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
public class SliderParams
|
public class SliderParams
|
||||||
{
|
{
|
||||||
public int Min{ get; set; }
|
public int Min { get; set; }
|
||||||
public int Max { get; set; }
|
public int Max { get; set; }
|
||||||
public int Gap { get; set; } = 0;
|
public int Gap { get; set; } = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
public class SliderRangeParams
|
public class SliderRangeParams
|
||||||
{
|
{
|
||||||
public int Min{ get; set; }
|
public int Min { get; set; }
|
||||||
public int Max { get; set; }
|
public int Max { get; set; }
|
||||||
public int Gap { get; set; } = 0;
|
public int Gap { get; set; } = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public static class Icons
|
|||||||
public readonly static MarkupString Triangle = new(OpenBraket +
|
public readonly static MarkupString Triangle = new(OpenBraket +
|
||||||
"<path d=\"M1 3H23L12 22\" />" +
|
"<path d=\"M1 3H23L12 22\" />" +
|
||||||
CloseBraket);
|
CloseBraket);
|
||||||
|
|
||||||
public readonly static MarkupString Close = new(OpenBraket +
|
public readonly static MarkupString Close = new(OpenBraket +
|
||||||
"<path d=\"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z\" />" +
|
"<path d=\"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z\" />" +
|
||||||
CloseBraket);
|
CloseBraket);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
namespace GameIdeas.Resources;
|
namespace GameIdeas.Resources;
|
||||||
|
|
||||||
public class Translations (TranslationService translationService)
|
public class Translations(TranslationService translationService)
|
||||||
{
|
{
|
||||||
public string GamesIdeas => translationService.Translate(nameof(GamesIdeas));
|
public string GamesIdeas => translationService.Translate(nameof(GamesIdeas));
|
||||||
public string ManualAdd => translationService.Translate(nameof(ManualAdd));
|
public string ManualAdd => translationService.Translate(nameof(ManualAdd));
|
||||||
|
|||||||
@@ -5,22 +5,22 @@ namespace GameIdeas.Resources;
|
|||||||
|
|
||||||
public class TranslationService
|
public class TranslationService
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, Dictionary<string, string>?> _translations = new();
|
private readonly Dictionary<string, Dictionary<string, string>?> _translations = [];
|
||||||
|
|
||||||
public void Initialize(Dictionary<string, string> translations)
|
public void Initialize(Dictionary<string, string> translations)
|
||||||
{
|
{
|
||||||
foreach (var translation in translations)
|
foreach (var translation in translations)
|
||||||
{
|
{
|
||||||
var json = JsonSerializer.Deserialize<Dictionary<string, string>>(translation.Value);
|
var json = JsonSerializer.Deserialize<Dictionary<string, string>>(translation.Value);
|
||||||
_translations[translation.Key] = json;
|
_translations[translation.Key] = json;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Translate(string key, string? culture = "fr")
|
public string Translate(string key, string? culture = "fr")
|
||||||
{
|
{
|
||||||
culture ??= CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
|
culture ??= CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
|
||||||
if (_translations.TryGetValue(culture, out var value) && value?.TryGetValue(key, out var translate) == true)
|
if (_translations.TryGetValue(culture, out var value) && value?.TryGetValue(key, out var translate) == true)
|
||||||
return translate;
|
return translate;
|
||||||
return key; // Fallback to key if translation is missing
|
return key; // Fallback to key if translation is missing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,5 +8,5 @@ public class CategoriesDto
|
|||||||
public List<DeveloperDto>? Developers { get; set; }
|
public List<DeveloperDto>? Developers { get; set; }
|
||||||
public List<PublisherDto>? Publishers { get; set; }
|
public List<PublisherDto>? Publishers { get; set; }
|
||||||
public List<int>? ReleaseYears { get; set; }
|
public List<int>? ReleaseYears { get; set; }
|
||||||
public List<StorageSpaceDto>? StorageSpaces { get; set; }
|
public List<StorageSpaceDto>? StorageSpaces { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using GameIdeas.Shared.Enum;
|
namespace GameIdeas.Shared.Dto;
|
||||||
|
|
||||||
namespace GameIdeas.Shared.Dto;
|
|
||||||
|
|
||||||
public class UserDto
|
public class UserDto
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,4 +31,3 @@ public partial class Game
|
|||||||
public virtual ICollection<GameProperty> GameProperties { get; set; }
|
public virtual ICollection<GameProperty> GameProperties { get; set; }
|
||||||
public virtual ICollection<GameTag> GameTags { get; set; }
|
public virtual ICollection<GameTag> GameTags { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ namespace GameIdeas.WebAPI.Context;
|
|||||||
|
|
||||||
public class GameIdeasContext : IdentityDbContext<User>
|
public class GameIdeasContext : IdentityDbContext<User>
|
||||||
{
|
{
|
||||||
public GameIdeasContext(DbContextOptions<GameIdeasContext> option)
|
public GameIdeasContext(DbContextOptions<GameIdeasContext> option)
|
||||||
: base(option)
|
: base(option)
|
||||||
{
|
{
|
||||||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
||||||
@@ -25,14 +25,16 @@ public class GameIdeasContext : IdentityDbContext<User>
|
|||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
modelBuilder.Entity<Developer>(entity => {
|
modelBuilder.Entity<Developer>(entity =>
|
||||||
|
{
|
||||||
entity.ToTable("Developer");
|
entity.ToTable("Developer");
|
||||||
|
|
||||||
entity.HasIndex(e => e.Name)
|
entity.HasIndex(e => e.Name)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<Platform>(entity => {
|
modelBuilder.Entity<Platform>(entity =>
|
||||||
|
{
|
||||||
entity.ToTable("Platform");
|
entity.ToTable("Platform");
|
||||||
|
|
||||||
entity.HasIndex(e => e.Label)
|
entity.HasIndex(e => e.Label)
|
||||||
@@ -41,18 +43,18 @@ public class GameIdeasContext : IdentityDbContext<User>
|
|||||||
|
|
||||||
modelBuilder.Entity<Property>(entity =>
|
modelBuilder.Entity<Property>(entity =>
|
||||||
{
|
{
|
||||||
entity.ToTable("Property");
|
entity.ToTable("Property");
|
||||||
|
|
||||||
entity.HasIndex(e => e.Label)
|
entity.HasIndex(e => e.Label)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<Publisher>(entity =>
|
modelBuilder.Entity<Publisher>(entity =>
|
||||||
{
|
{
|
||||||
entity.ToTable("Publisher");
|
entity.ToTable("Publisher");
|
||||||
|
|
||||||
entity.HasIndex(e => e.Name)
|
entity.HasIndex(e => e.Name)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<Tag>(entity =>
|
modelBuilder.Entity<Tag>(entity =>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace GameIdeas.WebAPI.Controllers;
|
|||||||
|
|
||||||
public class GameController(
|
public class GameController(
|
||||||
IGameReadService gameReadService,
|
IGameReadService gameReadService,
|
||||||
IGameWriteService gameWriteService,
|
IGameWriteService gameWriteService,
|
||||||
ILoggerFactory loggerFactory) : Controller
|
ILoggerFactory loggerFactory) : Controller
|
||||||
{
|
{
|
||||||
private readonly ILogger<GameController> logger = loggerFactory.CreateLogger<GameController>();
|
private readonly ILogger<GameController> logger = loggerFactory.CreateLogger<GameController>();
|
||||||
@@ -73,7 +73,7 @@ public class GameController(
|
|||||||
{
|
{
|
||||||
logger.LogError(e, "Internal error while update game");
|
logger.LogError(e, "Internal error while update game");
|
||||||
return StatusCode(500, e.Message);
|
return StatusCode(500, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Roles = GlobalConstants.ADMIN_MEMBER)]
|
[Authorize(Roles = GlobalConstants.ADMIN_MEMBER)]
|
||||||
|
|||||||
@@ -5,32 +5,32 @@ namespace GameIdeas.WebAPI.Controllers;
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
|
|
||||||
public class TranslationsController (ILogger<TranslationsController> Logger) : ControllerBase
|
public class TranslationsController(ILogger<TranslationsController> Logger) : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetTranslations()
|
public async Task<IActionResult> GetTranslations()
|
||||||
{
|
{
|
||||||
var dictionary = new Dictionary<string, string>();
|
var dictionary = new Dictionary<string, string>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var filesDirectory = Path.Combine(
|
var filesDirectory = Path.Combine(
|
||||||
Directory.GetCurrentDirectory(),
|
Directory.GetCurrentDirectory(),
|
||||||
"Files");
|
"Files");
|
||||||
var translationFiles = Directory.GetFiles(filesDirectory, "*.json");
|
var translationFiles = Directory.GetFiles(filesDirectory, "*.json");
|
||||||
foreach (var file in translationFiles)
|
foreach (var file in translationFiles)
|
||||||
{
|
{
|
||||||
var name = file.Split('.');
|
var name = file.Split('.');
|
||||||
var culture = name[^2];
|
var culture = name[^2];
|
||||||
var content = await System.IO.File.ReadAllTextAsync(file);
|
var content = await System.IO.File.ReadAllTextAsync(file);
|
||||||
dictionary.Add(culture, content);
|
dictionary.Add(culture, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Internal translations error");
|
Logger.LogError(ex, "Internal translations error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(dictionary);
|
return Ok(dictionary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,22 +19,22 @@ public class UserController(
|
|||||||
[HttpPost("Login")]
|
[HttpPost("Login")]
|
||||||
public async Task<ActionResult<TokenDto>> Login([FromBody] UserDto model)
|
public async Task<ActionResult<TokenDto>> Login([FromBody] UserDto model)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Ok(await userReadService.Login(model));
|
return Ok(await userReadService.Login(model));
|
||||||
}
|
}
|
||||||
catch (UserInvalidException e)
|
catch (UserInvalidException e)
|
||||||
{
|
{
|
||||||
logger.LogInformation(e, "Missing informations for authentication");
|
logger.LogInformation(e, "Missing informations for authentication");
|
||||||
return StatusCode(406, e.Message);
|
return StatusCode(406, e.Message);
|
||||||
}
|
}
|
||||||
catch (UserUnauthorizedException e)
|
catch (UserUnauthorizedException e)
|
||||||
{
|
{
|
||||||
logger.LogWarning(e, "Authentication invalid with there informations");
|
logger.LogWarning(e, "Authentication invalid with there informations");
|
||||||
return Unauthorized(e.Message);
|
return Unauthorized(e.Message);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.LogError(e, "Internal error while search games");
|
logger.LogError(e, "Internal error while search games");
|
||||||
return StatusCode(500, e.Message);
|
return StatusCode(500, e.Message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
namespace GameIdeas.WebAPI.Exceptions;
|
namespace GameIdeas.WebAPI.Exceptions;
|
||||||
|
|
||||||
public class UserInvalidException (string message) : Exception(message);
|
public class UserInvalidException(string message) : Exception(message);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace GameIdeas.WebAPI.Migrations
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.Sql(@$"DELETE FROM ""AspNetUserRoles"" WHERE ""UserId"" = '{GlobalConstants.ADMINISTRATOR_USER_ID.ToString()}' AND ""RoleId"" = '{GlobalConstants.ADMINISTRATOR_ID.ToString()}'");
|
migrationBuilder.Sql(@$"DELETE FROM ""AspNetUserRoles"" WHERE ""UserId"" = '{GlobalConstants.ADMINISTRATOR_USER_ID}' AND ""RoleId"" = '{GlobalConstants.ADMINISTRATOR_ID}'");
|
||||||
migrationBuilder.DeleteData("AspNetUsers", "Id", GlobalConstants.ADMINISTRATOR_USER_ID.ToString());
|
migrationBuilder.DeleteData("AspNetUsers", "Id", GlobalConstants.ADMINISTRATOR_USER_ID.ToString());
|
||||||
migrationBuilder.DeleteData("AspNetRoles", "Id", GlobalConstants.ADMINISTRATOR_ID.ToString());
|
migrationBuilder.DeleteData("AspNetRoles", "Id", GlobalConstants.ADMINISTRATOR_ID.ToString());
|
||||||
migrationBuilder.DeleteData("AspNetRoles", "Id", GlobalConstants.MEMBER_ID.ToString());
|
migrationBuilder.DeleteData("AspNetRoles", "Id", GlobalConstants.MEMBER_ID.ToString());
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ services.AddIdentity<User, IdentityRole>()
|
|||||||
.AddDefaultTokenProviders();
|
.AddDefaultTokenProviders();
|
||||||
|
|
||||||
var jwtKey = Environment.GetEnvironmentVariable("JWT_KEY")
|
var jwtKey = Environment.GetEnvironmentVariable("JWT_KEY")
|
||||||
?? throw new ArgumentNullException(message: "Invalid key for JWT token", null);
|
?? throw new ArgumentNullException(message: "Invalid key for JWT token", null);
|
||||||
|
|
||||||
services.AddAuthentication(options =>
|
services.AddAuthentication(options =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class GameReadService(GameIdeasContext context, IMapper mapper, ICategory
|
|||||||
Expression propertyAccess = Expression.PropertyOrField(param, filter.SortPropertyName);
|
Expression propertyAccess = Expression.PropertyOrField(param, filter.SortPropertyName);
|
||||||
var converted = Expression.Convert(propertyAccess, typeof(object));
|
var converted = Expression.Convert(propertyAccess, typeof(object));
|
||||||
var lambda = Expression.Lambda<Func<Game, object>>(converted, param);
|
var lambda = Expression.Lambda<Func<Game, object>>(converted, param);
|
||||||
|
|
||||||
if (filter.SortType == Shared.Enum.SortType.Ascending)
|
if (filter.SortType == Shared.Enum.SortType.Ascending)
|
||||||
{
|
{
|
||||||
query = Queryable.OrderBy(query, lambda);
|
query = Queryable.OrderBy(query, lambda);
|
||||||
@@ -116,7 +116,7 @@ public class GameReadService(GameIdeasContext context, IMapper mapper, ICategory
|
|||||||
|
|
||||||
if (filter.ReleaseYears != null)
|
if (filter.ReleaseYears != null)
|
||||||
{
|
{
|
||||||
query = query.Where(game => game.ReleaseDate != null &&
|
query = query.Where(game => game.ReleaseDate != null &&
|
||||||
filter.ReleaseYears.Contains(game.ReleaseDate.Value.Year));
|
filter.ReleaseYears.Contains(game.ReleaseDate.Value.Year));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,15 +130,14 @@ public class GameReadService(GameIdeasContext context, IMapper mapper, ICategory
|
|||||||
.Select(k => k.Trim())
|
.Select(k => k.Trim())
|
||||||
.ToArray() ?? [];
|
.ToArray() ?? [];
|
||||||
|
|
||||||
games = games
|
games = [.. games
|
||||||
.Where(game => keywords.All(
|
.Where(game => keywords.All(
|
||||||
kw => game.Title.Contains(kw, StringComparison.OrdinalIgnoreCase)
|
kw => game.Title.Contains(kw, StringComparison.OrdinalIgnoreCase)
|
||||||
))
|
))
|
||||||
.OrderBy(game => keywords.Min(kw =>
|
.OrderBy(game => keywords.Min(kw =>
|
||||||
game.Title.IndexOf(kw, StringComparison.OrdinalIgnoreCase)
|
game.Title.IndexOf(kw, StringComparison.OrdinalIgnoreCase)
|
||||||
))
|
))
|
||||||
.ThenBy(game => game.Title.Length)
|
.ThenBy(game => game.Title.Length)];
|
||||||
.ToList();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -147,10 +146,9 @@ public class GameReadService(GameIdeasContext context, IMapper mapper, ICategory
|
|||||||
{
|
{
|
||||||
var storageSpaces = categoryService.GetStorageSpaces().Where(stor => filter.StorageSpaces.Contains(stor.Id));
|
var storageSpaces = categoryService.GetStorageSpaces().Where(stor => filter.StorageSpaces.Contains(stor.Id));
|
||||||
|
|
||||||
games = games
|
games = [.. games
|
||||||
.Where(game => storageSpaces.Any(stor =>
|
.Where(game => storageSpaces.Any(stor =>
|
||||||
(stor.MinSize ?? int.MinValue) <= game.StorageSpace && (stor.MaxSize ?? int.MaxValue) > game.StorageSpace))
|
(stor.MinSize ?? int.MinValue) <= game.StorageSpace && (stor.MaxSize ?? int.MaxValue) > game.StorageSpace))];
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,15 +91,14 @@ public class UserReadService(
|
|||||||
.Select(k => k.Trim())
|
.Select(k => k.Trim())
|
||||||
.ToArray() ?? [];
|
.ToArray() ?? [];
|
||||||
|
|
||||||
users = users
|
users = [.. users
|
||||||
.Where(user => keywords.All(
|
.Where(user => keywords.All(
|
||||||
kw => user.UserName?.Contains(kw, StringComparison.OrdinalIgnoreCase) ?? true
|
kw => user.UserName?.Contains(kw, StringComparison.OrdinalIgnoreCase) ?? true
|
||||||
))
|
))
|
||||||
.OrderBy(user => keywords.Min(kw =>
|
.OrderBy(user => keywords.Min(kw =>
|
||||||
user.UserName?.IndexOf(kw, StringComparison.OrdinalIgnoreCase)
|
user.UserName?.IndexOf(kw, StringComparison.OrdinalIgnoreCase)
|
||||||
))
|
))
|
||||||
.ThenBy(user => user.UserName?.Length)
|
.ThenBy(user => user.UserName?.Length)];
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using AutoMapper;
|
using GameIdeas.Resources;
|
||||||
using GameIdeas.Resources;
|
|
||||||
using GameIdeas.Shared.Dto;
|
using GameIdeas.Shared.Dto;
|
||||||
using GameIdeas.Shared.Model;
|
using GameIdeas.Shared.Model;
|
||||||
using GameIdeas.WebAPI.Exceptions;
|
using GameIdeas.WebAPI.Exceptions;
|
||||||
@@ -12,8 +11,8 @@ public class UserWriteService(
|
|||||||
{
|
{
|
||||||
public async Task<string> CreateUser(UserDto user)
|
public async Task<string> CreateUser(UserDto user)
|
||||||
{
|
{
|
||||||
if (user.Username == null ||
|
if (user.Username == null ||
|
||||||
user.Password == null ||
|
user.Password == null ||
|
||||||
user.Role == null)
|
user.Role == null)
|
||||||
{
|
{
|
||||||
throw new UserInvalidException(ResourcesKey.MissingField);
|
throw new UserInvalidException(ResourcesKey.MissingField);
|
||||||
@@ -75,7 +74,7 @@ public class UserWriteService(
|
|||||||
{
|
{
|
||||||
var roles = await userManager.GetRolesAsync(userToUpdate);
|
var roles = await userManager.GetRolesAsync(userToUpdate);
|
||||||
await userManager.RemoveFromRolesAsync(userToUpdate, roles);
|
await userManager.RemoveFromRolesAsync(userToUpdate, roles);
|
||||||
await userManager.AddToRoleAsync(userToUpdate, user.Role.Name);
|
await userManager.AddToRoleAsync(userToUpdate, user.Role.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return userToUpdate.Id;
|
return userToUpdate.Id;
|
||||||
|
|||||||
Reference in New Issue
Block a user