diff --git a/NetinaShop.AdminPanel.PWA/App.razor b/NetinaShop.AdminPanel.PWA/App.razor index 6fd3ed1..cf43171 100644 --- a/NetinaShop.AdminPanel.PWA/App.razor +++ b/NetinaShop.AdminPanel.PWA/App.razor @@ -1,7 +1,15 @@ - +@using NetinaShop.AdminPanel.PWA.Pages +@inject NavigationManager NavigationManager + - - + + + + + + + + Not found @@ -9,4 +17,6 @@

Sorry, there's nothing at this address.

+ +
diff --git a/NetinaShop.AdminPanel.PWA/Dialogs/BrandActionDialogBox.razor b/NetinaShop.AdminPanel.PWA/Dialogs/BrandActionDialogBox.razor new file mode 100644 index 0000000..4bc2128 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Dialogs/BrandActionDialogBox.razor @@ -0,0 +1,5 @@ +

BrandActionDialogBox

+ +@code { + +} diff --git a/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor b/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor index 0f7ee14..a467bd3 100644 --- a/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor +++ b/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor @@ -1,6 +1,9 @@ -@using Blazorise.Extensions +@using NetinaShop.Common.Models.Exception +@using NetinaShop.Domain.CommandQueries.Commands + @inject ISnackbar Snackbar @inject IRestWrapper RestWrapper +@inject IUserUtility UserUtility @@ -63,6 +66,32 @@ void Submit() => MudDialog.Close(DialogResult.Ok(true)); void Cancel() => MudDialog.Cancel(); + private string _name; + private string _description; + private bool _isMain; + + private async Task SubmitCreateAsync() + { + try + { + if (_name.IsNullOrEmpty()) + throw new AppException("لطفا نام دسته را وارد کنید"); + var token = await UserUtility.GetBearerTokenAsync(); + var request = new ProductCreateCategoryCommand(_name, _description, _selectedCategory?.Id ?? default, new List()); + await RestWrapper.CrudApiRest(Address.ProductCategoryController).Create(request, token); + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + Snackbar.Add(exe.Message, Severity.Error); + Snackbar.Add(ex.Content, Severity.Error); + } + catch (Exception e) + { + Snackbar.Add(e.Message, Severity.Error); + } + } private List _productCategories = new List(); private ProductCategorySDto? _selectedCategory; diff --git a/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor b/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor index 8d218c6..d1f2cdc 100644 --- a/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor +++ b/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor @@ -22,47 +22,71 @@ color: #fff !important; } - - - - - - - - - - - - - - امیرحسین خادمی - 09214802813 - - - - - - + + + + + + - - - - - - + + + + + + + + + + امیرحسین خادمی + 09214802813 + + + + + + + + + + + + + + +
+ @Body +
+ +
+
+
+
+
+
+ +
+ + + + + + +
@Body
- -
-
-
+ + + + + @code { MudTheme MyCustomTheme = new MudTheme() diff --git a/NetinaShop.AdminPanel.PWA/Models/Address.cs b/NetinaShop.AdminPanel.PWA/Models/Address.cs index 22cd41f..d8d5b38 100644 --- a/NetinaShop.AdminPanel.PWA/Models/Address.cs +++ b/NetinaShop.AdminPanel.PWA/Models/Address.cs @@ -11,4 +11,5 @@ public static class Address public static string AuthController = $"{BaseAddress}/auth"; public static string UserController = $"{BaseAddress}/user"; public static string ProductCategoryController = $"{BaseAddress}/product/category"; + public static string BrandController = $"{BaseAddress}/brand"; } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj b/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj index ce257a5..0bc8a82 100644 --- a/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj +++ b/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj @@ -14,11 +14,13 @@ - - - + + + + + - + @@ -40,10 +42,19 @@ + + + + + + + + + diff --git a/NetinaShop.AdminPanel.PWA/Pages/BrandsPage.razor b/NetinaShop.AdminPanel.PWA/Pages/BrandsPage.razor index 3691a9b..a5e4ff6 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/BrandsPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/BrandsPage.razor @@ -1,6 +1,80 @@ @page "/BrandsPage" -

BrandsPage

+@inject IDialogService DialogService +@inject NavigationManager NavigationManager +@inject IRestWrapper RestWrapper +@inject ISnackbar Snackbar +@inject IUserUtility UserUtility + + + + + + + برنــــدها + 124 عدد + + + افزودن برند + + + + + + + + + + + + @if (@context.Item.HasSpecialPage) + { +

بلی

+ } + else + { +

خیر

+ + } +
+
+ + + + + + + + +
+
+
+
+
+
+ +@code +{ + public BrandsPageViewModel ViewModel { get; set; } + protected override async Task OnInitializedAsync() + { + ViewModel = new BrandsPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService); + await ViewModel.InitializeAsync(); + await base.OnInitializedAsync(); + } + +} @code { diff --git a/NetinaShop.AdminPanel.PWA/Pages/BrandsPage.razor.cs b/NetinaShop.AdminPanel.PWA/Pages/BrandsPage.razor.cs new file mode 100644 index 0000000..19c1670 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Pages/BrandsPage.razor.cs @@ -0,0 +1,90 @@ +using NetinaShop.Domain.Entities.Brands; + +namespace NetinaShop.AdminPanel.PWA.Pages; + +public class BrandsPageViewModel : BaseViewModel> +{ + private readonly NavigationManager _navigationManager; + private readonly ISnackbar _snackbar; + private readonly IUserUtility _userUtility; + private readonly IDialogService _dialogService; + private readonly IRestWrapper _restWrapper; + + public BrandsPageViewModel(NavigationManager navigationManager, ISnackbar snackbar, IUserUtility userUtility, IRestWrapper restWrapper, IDialogService dialogService) + { + _navigationManager = navigationManager; + _snackbar = snackbar; + _userUtility = userUtility; + _restWrapper = restWrapper; + _dialogService = dialogService; + } + + public override async Task InitializeAsync() + { + try + { + IsProcessing = true; + var dto = await _restWrapper.CrudDtoApiRest(Address.BrandController) + .ReadAll(0); + PageDto = dto; + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + } + finally + { + + IsProcessing = false; + } + await base.InitializeAsync(); + } + + public async Task AddBrandClicked() + { + DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; + await _dialogService.ShowAsync("افزودن برند جدید", maxWidth); + } + + public async Task DeleteBrandAsync(Guid selectedCategoryId) + { + var options = new DialogOptions { CloseOnEscapeKey = true }; + var parameters = new DialogParameters(); + parameters.Add(x => x.ContentText, "آیا از حذف برند اطمینان دارید ?"); + var dialogReference = await _dialogService.ShowAsync("حذف برند", parameters, options); + var result = await dialogReference.Result; + if (!result.Canceled) + { + + try + { + + IsProcessing = true; + var token = await _userUtility.GetBearerTokenAsync(); + await _restWrapper.CrudDtoApiRest(Address.BrandController) + .Delete(selectedCategoryId, token); + _snackbar.Add("حذف برند با موفقیت انجام شد", Severity.Success); + + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + } + finally + { + + IsProcessing = false; + } + } + } +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor b/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor index e902692..9c5af7d 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor @@ -1,5 +1,4 @@ @page "/CategoriesPage" -@using NetinaShop.AdminPanel.PWA.Utilities @inject IDialogService DialogService @inject NavigationManager NavigationManager @inject IRestWrapper RestWrapper diff --git a/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor.cs b/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor.cs index 46e552d..3ac379c 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor.cs +++ b/NetinaShop.AdminPanel.PWA/Pages/CategoriesPage.razor.cs @@ -1,14 +1,4 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using MudBlazor; -using NetinaShop.AdminPanel.PWA.Dialogs; -using NetinaShop.AdminPanel.PWA.Dialogs.Originals; -using NetinaShop.AdminPanel.PWA.Models.Api; -using NetinaShop.AdminPanel.PWA.Services.RestServices; -using NetinaShop.AdminPanel.PWA.Utilities; -using NetinaShop.Domain.Entities.ProductCategories; - -namespace NetinaShop.AdminPanel.PWA.Pages; +namespace NetinaShop.AdminPanel.PWA.Pages; public class CategoriesPageViewModel : BaseViewModel> { diff --git a/NetinaShop.AdminPanel.PWA/Pages/Home.razor b/NetinaShop.AdminPanel.PWA/Pages/Home.razor index 43565ac..13a1ca7 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/Home.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/Home.razor @@ -1,4 +1,6 @@ -@page "/HomePage" + +@page "/" +@attribute [Microsoft.AspNetCore.Authorization.Authorize] diff --git a/NetinaShop.AdminPanel.PWA/Pages/LoginPage.razor b/NetinaShop.AdminPanel.PWA/Pages/LoginPage.razor new file mode 100644 index 0000000..841362b --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Pages/LoginPage.razor @@ -0,0 +1,6 @@ +@page "/LoginPage" +

LoginPage

+ +@code { + +} diff --git a/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor b/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor index dcbf687..90f11e7 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor @@ -1,5 +1,6 @@ @page "/ProductsPage" -@using NetinaShop.AdminPanel.PWA.Dialogs +@attribute [Microsoft.AspNetCore.Authorization.Authorize] + @inject IDialogService DialogService diff --git a/NetinaShop.AdminPanel.PWA/Program.cs b/NetinaShop.AdminPanel.PWA/Program.cs index 6e81247..73cf0fa 100644 --- a/NetinaShop.AdminPanel.PWA/Program.cs +++ b/NetinaShop.AdminPanel.PWA/Program.cs @@ -1,9 +1,11 @@ using Blazored.LocalStorage; +using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using MudBlazor; using MudBlazor.Services; using NetinaShop.AdminPanel.PWA; +using NetinaShop.AdminPanel.PWA.Services; using NetinaShop.AdminPanel.PWA.Services.RestServices; using NetinaShop.AdminPanel.PWA.Utilities; using Toolbelt.Blazor.Extensions.DependencyInjection; @@ -11,6 +13,12 @@ using Toolbelt.Blazor.Extensions.DependencyInjection; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); +builder.Services.AddCascadingAuthenticationState(); +builder.Services.AddOptions(); +builder.Services.AddAuthorizationCore(); +builder.Services.AddApiAuthorization(); +builder.Services.AddScoped(); builder.Services.AddMudServices(config => { config.SnackbarConfiguration.VisibleStateDuration = 3500; diff --git a/NetinaShop.AdminPanel.PWA/Services/CustomAuthenticationStateProvider.cs b/NetinaShop.AdminPanel.PWA/Services/CustomAuthenticationStateProvider.cs new file mode 100644 index 0000000..9535296 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Services/CustomAuthenticationStateProvider.cs @@ -0,0 +1,32 @@ +using System.Security.Claims; +using Blazorise.Extensions; +using Microsoft.AspNetCore.Components.Authorization; + +namespace NetinaShop.AdminPanel.PWA.Services; + +public class CustomAuthenticationStateProvider : AuthenticationStateProvider +{ + private readonly IUserUtility _userUtility; + + public CustomAuthenticationStateProvider(IUserUtility userUtility) + { + _userUtility = userUtility; + } + public override async Task GetAuthenticationStateAsync() + { + var token = await _userUtility.GetBearerTokenAsync(); + if (token.IsNullOrEmpty()) + { + return new AuthenticationState(new()); + } + var identity = new ClaimsIdentity(new[] + { + new Claim(ClaimTypes.Name, "mrfibuli"), + }, "Custom Authentication"); + + var user = new ClaimsPrincipal(identity); + + + return new AuthenticationState(user); + } +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs index 53d7e56..6948deb 100644 --- a/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs @@ -5,7 +5,7 @@ namespace NetinaShop.AdminPanel.PWA.Services.RestServices; public interface ICrudApiRest where T : class { [Post("")] - Task Create([Body] T payload, [Header("Authorization")] string authorization); + Task Create([Body] TCreateCommand payload, [Header("Authorization")] string authorization); [Get("")] Task> ReadAll([Query] int page,[Header("Authorization")] string authorization); @@ -28,7 +28,7 @@ public interface ICrudDtoApiRest where T : class where TDto : Task Create([Body] TDto payload, [Header("Authorization")] string authorization); [Get("")] - Task> ReadAll([Query]int page,[Header("Authorization")] string authorization); + Task> ReadAll([Query]int page); [Get("")] Task> ReadAll(); diff --git a/NetinaShop.AdminPanel.PWA/_Imports.razor b/NetinaShop.AdminPanel.PWA/_Imports.razor index 6a75c3d..3a0ccc4 100644 --- a/NetinaShop.AdminPanel.PWA/_Imports.razor +++ b/NetinaShop.AdminPanel.PWA/_Imports.razor @@ -20,4 +20,7 @@ @using NetinaShop.AdminPanel.PWA.Models @using Refit @using NetinaShop.Domain.Entities.ProductCategories -@using NetinaShop.AdminPanel.PWA.Services.RestServices \ No newline at end of file +@using NetinaShop.AdminPanel.PWA.Services.RestServices +@using Blazorise.Extensions +@using NetinaShop.AdminPanel.PWA.Utilities +@using Microsoft.AspNetCore.Components.Authorization diff --git a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css index 67cbfdc..006cfc2 100644 --- a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css +++ b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css @@ -598,6 +598,10 @@ video { margin-right: 0.5rem; } +.mt-3 { + margin-top: 0.75rem; +} + .mt-4 { margin-top: 1rem; } @@ -606,10 +610,6 @@ video { margin-top: 1.25rem; } -.mt-3 { - margin-top: 0.75rem; -} - .flex { display: flex; }