diff --git a/NetinaShop.AdminPanel.PWA/Components/Originals/BaseButtonUi.razor b/NetinaShop.AdminPanel.PWA/Components/Originals/BaseButtonUi.razor index 19dde05..5031182 100644 --- a/NetinaShop.AdminPanel.PWA/Components/Originals/BaseButtonUi.razor +++ b/NetinaShop.AdminPanel.PWA/Components/Originals/BaseButtonUi.razor @@ -2,6 +2,7 @@ Color="@Color" @onclick="OnClickCallback" @attributes="CapturedAttributes" + Size="Size" Disabled="IsProcessing" DisableElevation="true" > @@ -47,6 +48,9 @@ [Parameter] public bool IsProcessing { get; set; } = false; + [Parameter] + public Size Size { get; set; } = Size.Medium; + [Parameter] public EventCallback OnClickCallback { get; set; } diff --git a/NetinaShop.AdminPanel.PWA/Components/Originals/RichTextEditorUi.razor b/NetinaShop.AdminPanel.PWA/Components/Originals/RichTextEditorUi.razor index bf1fd96..c660b68 100644 --- a/NetinaShop.AdminPanel.PWA/Components/Originals/RichTextEditorUi.razor +++ b/NetinaShop.AdminPanel.PWA/Components/Originals/RichTextEditorUi.razor @@ -1,25 +1,36 @@ @inject IJSRuntime JsRuntime +@implements IAsyncDisposable
@@ -307,7 +267,7 @@ - + @if (ViewModel.IsEditing) { diff --git a/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor.cs b/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor.cs index 3ef885d..6bebad3 100644 --- a/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor.cs +++ b/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor.cs @@ -80,7 +80,8 @@ public class ProductActionDialogBoxViewModel : BaseViewModel try { IsProcessing = true; - var productLDto = await _restWrapper.CrudDtoApiRest(Address.ProductController).ReadOne(_product.Id); + var response = await _restWrapper.ProductRestApi.ReadOne(_product.Id); + var productLDto = response.Product; PageDto.ExpertCheck = productLDto.ExpertCheck; PageDto.Summery = productLDto.Summery; PageDto.BeDisplayed = productLDto.BeDisplayed; diff --git a/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor b/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor index 77d7189..7be532c 100644 --- a/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor +++ b/NetinaShop.AdminPanel.PWA/Layout/MainLayout.razor @@ -40,8 +40,8 @@ - - + + @* @@ -53,14 +53,18 @@ @_user?.PhoneNumber - + @* *@ + + + + - + @@ -73,7 +77,7 @@
- +
@@ -101,6 +105,8 @@ private string _updateText = "! نسخه جدید پنل ادمین رسید"; private ApplicationUserSDto? _user; + bool open = false; + void ToggleDrawer() => open = !open; private async Task LogoutAsync() { await UserUtility.LogoutAsync(); @@ -118,11 +124,6 @@ protected override async Task OnInitializedAsync() { _user = await UserUtility.GetUserAsync(); - await base.OnInitializedAsync(); } - - private void Callback(PWAUpdater.States obj) - { - } } diff --git a/NetinaShop.AdminPanel.PWA/Models/Address.cs b/NetinaShop.AdminPanel.PWA/Models/Address.cs index 2c4bd73..ab97bc7 100644 --- a/NetinaShop.AdminPanel.PWA/Models/Address.cs +++ b/NetinaShop.AdminPanel.PWA/Models/Address.cs @@ -19,4 +19,8 @@ public static class Address public static string DiscountController => $"{BaseAddress}/discount"; public static string RoleController => $"{BaseAddress}/user/role"; public static string ShippingController => $"{BaseAddress}/warehouse/shipping"; + public static string OrderController => $"{BaseAddress}/order"; + public static string PaymentController => $"{BaseAddress}/accounting/pay"; + public static string PageController => $"{BaseAddress}/page"; + public static string ScraperController => $"{BaseAddress}/scraper"; } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Models/OrderTest.cs b/NetinaShop.AdminPanel.PWA/Models/OrderTest.cs new file mode 100644 index 0000000..428a17c --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Models/OrderTest.cs @@ -0,0 +1,30 @@ +namespace NetinaShop.AdminPanel.PWA.Models; + +// Root myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); +public class OrderProduct +{ + public int Count { get; set; } + public string Id { get; set; } +} + +public class OrderTest +{ + public string FactorCode { get; set; } + public int TotalPrice { get; set; } + public int DeliveryPrice { get; set; } + public int TaxesPrice { get; set; } + public int ServicePrice { get; set; } + public int PackingPrice { get; set; } + public int TotalProductsPrice { get; set; } + public int DiscountPrice { get; set; } + public bool IsPayed { get; set; } + public int OrderStatus { get; set; } + public DateTime DoneAt { get; set; } + public DateTime OrderAt { get; set; } + public int PreparingMinute { get; set; } + public string DiscountCode { get; set; } + public List OrderProducts { get; set; } + public List OrderDeliveries { get; set; } + public string Id { get; set; } +} + diff --git a/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj b/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj index ad49088..b761655 100644 --- a/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj +++ b/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj @@ -5,8 +5,9 @@ enable enable service-worker-assets.js - 0.4.3.12 - 0.4.3.12 + 0.6.12.22 + 0.6.12.22 + $(MSBuildProjectName) @@ -38,10 +39,6 @@ - - - - diff --git a/NetinaShop.AdminPanel.PWA/Pages/FaqManagementPage.razor b/NetinaShop.AdminPanel.PWA/Pages/FaqManagementPage.razor new file mode 100644 index 0000000..add127d --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Pages/FaqManagementPage.razor @@ -0,0 +1,66 @@ +@page "/faqs" +@attribute [Microsoft.AspNetCore.Authorization.Authorize] + +@inject IDialogService DialogService +@inject NavigationManager NavigationManager +@inject ISnackbar Snackbar +@inject IUserUtility UserUtility +@inject IRestWrapper RestWrapper + + + + + + سوالات متداول فروشگاه من + + ذخیره سوالات + + + + + + + + + + افزودن + + + + + @foreach (var item in ViewModel.PageDto.Faqs) + { + + + + + + @item.Key + + + + @item.Value + + + } + + + + + + +@code +{ + public FaqManagementPageViewModel ViewModel { get; set; } + protected override async Task OnInitializedAsync() + { + ViewModel = new FaqManagementPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService); + await ViewModel.InitializeAsync(); + await base.OnInitializedAsync(); + } +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Pages/FaqManagementPage.razor.cs b/NetinaShop.AdminPanel.PWA/Pages/FaqManagementPage.razor.cs new file mode 100644 index 0000000..db0931e --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Pages/FaqManagementPage.razor.cs @@ -0,0 +1,139 @@ +using NetinaShop.Domain.Entities.Pages; + +namespace NetinaShop.AdminPanel.PWA.Pages; + +public class FaqManagementPageViewModel : BaseViewModel +{ + private readonly NavigationManager _navigationManager; + private readonly ISnackbar _snackbar; + private readonly IUserUtility _userUtility; + private readonly IDialogService _dialogService; + private readonly IRestWrapper _restWrapper; + + public FaqManagementPageViewModel(NavigationManager navigationManager, ISnackbar snackbar, IUserUtility userUtility, IRestWrapper restWrapper, IDialogService dialogService) + { + _navigationManager = navigationManager; + _snackbar = snackbar; + _userUtility = userUtility; + _restWrapper = restWrapper; + _dialogService = dialogService; + } + + + public string Question { get; set; } = string.Empty; + public string Answer { get; set; } = string.Empty; + private PageActionRequestDto? _request; + public override async Task InitializeAsync() + { + try + { + var token = await _userUtility.GetBearerTokenAsync(); + if (token == null) + throw new Exception("Token is null"); + IsProcessing = true; + PageDto.Faqs.Clear(); + var typeName = typeof(FAQPage).FullName; + var dto = await _restWrapper.PageRestApi.ReadByType(typeName, token); + if (!dto.Data.IsNullOrEmpty()) + { + + PageDto = dto.GetData(); + _request = new PageActionRequestDto + { + Name = dto.Name, + Content = dto.Content, + Description = dto.Description, + Id = dto.Id, + IsCustomPage = dto.IsCustomPage, + IsHtmlBasePage = dto.IsHtmlBasePage, + Slug = dto.Slug, + Type = typeof(FAQPage).FullName + }; + } + } + 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 SaveAsync() + { + try + { + var token = await _userUtility.GetBearerTokenAsync(); + if (token == null) + throw new Exception("Token is null"); + IsProcessing = true; + var request = new PageActionRequestDto + { + Name = "سوالات متداول", + Content = string.Empty, + Description = string.Empty, + Data = PageDto, + IsCustomPage = true, + IsHtmlBasePage = false, + Slug = "faq", + Type = typeof(FAQPage).FullName + }; + if (_request != null) + { + request = _request; + } + request.Data = PageDto; + await _restWrapper.PageRestApi.CreatePage(request, token); + } + 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; + } + } + public void AddNewQuestion() + { + try + { + if (Question.IsNullOrEmpty()) + throw new Exception("سوال را وارد کنید"); + if (Answer.IsNullOrEmpty()) + throw new Exception("پاسخ را وارد کنید"); + + PageDto.Faqs.Add(Question,Answer); + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + } + } + public void RemoveQuestion(string question) + { + try + { + PageDto.Faqs.Remove(question); + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + } + } +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor b/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor index 7d1285f..cc8e52e 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor @@ -44,34 +44,53 @@ - + OnAdornmentClick="@ViewModel.SearchAsync"> *@ - - - + + + + +

@context.Item.OrderAt.ToPersianDateTime().ToLongDateString()

+
+
+ + + +

@context.Item.PayedAt.ToPersianDateTime().ToLongDateString()

+
+
+ + + + +

@context.Item.TotalPrice.ToString("N0") ریالــ

+
+
+ + + +

@context.Item.OrderStatus.ToDisplay()

+
+
+ - - + OnClick="async () => await ViewModel.ShowClicked(context.Item)"/> @@ -79,7 +98,7 @@ - @@ -92,10 +111,10 @@ @code { - public BlogsPageViewModel ViewModel { get; set; } + public OrdersPageViewModel ViewModel { get; set; } protected override async Task OnInitializedAsync() { - ViewModel = new BlogsPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService); + ViewModel = new OrdersPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService); await ViewModel.InitializeAsync(); await base.OnInitializedAsync(); } diff --git a/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor.cs b/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor.cs index 073a70b..c39b35c 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor.cs +++ b/NetinaShop.AdminPanel.PWA/Pages/OrdersPage.razor.cs @@ -1,6 +1,109 @@ namespace NetinaShop.AdminPanel.PWA.Pages; -public class OrdersPageViewModel +public class OrdersPageViewModel : BaseViewModel { - + private readonly NavigationManager _navigationManager; + private readonly ISnackbar _snackbar; + private readonly IUserUtility _userUtility; + private readonly IDialogService _dialogService; + private readonly IRestWrapper _restWrapper; + + public string Search = string.Empty; + public int MainGridCurrentPage = 0; + public int MainGridPageCount = 1; + + public ObservableCollection MainOrders { get; } = new ObservableCollection(); + + public OrdersPageViewModel(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 + { + var token = await _userUtility.GetBearerTokenAsync(); + if (token == null) + throw new Exception("Token is null"); + IsProcessing = true; + MainOrders.Clear(); + var dto = await _restWrapper.OrderRestApi.ReadAll(MainGridCurrentPage, null, null, null,token); + dto.ForEach(d => MainOrders.Add(d)); + if (MainOrders.Count == 15) + MainGridPageCount = 2; + } + 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 ChangePageAsync(int page) + { + MainGridCurrentPage = page - 1; + if (MainGridCurrentPage > MainGridPageCount - 2) + { + + try + { + IsProcessing = true; + var token = await _userUtility.GetBearerTokenAsync(); + if (token == null) + throw new Exception("Token is null"); + + + var dto = await _restWrapper.OrderRestApi.ReadAll(MainGridCurrentPage, null, null, null, token); + dto.ForEach(d => MainOrders.Add(d)); + if (MainOrders.Count == 15) + MainGridPageCount = MainGridCurrentPage + 2; + + } + 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; + } + } + } + + + public async Task ShowClicked(OrderSDto order) + { + DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, NoHeader = true, FullWidth = true, DisableBackdropClick = true }; + var parameters = new DialogParameters(); + parameters.Add(x => x.Order, order); + var dialogResult = await _dialogService.ShowAsync($" سفارش {order.FactorCode}", parameters, maxWidth); + var result = await dialogResult.Result; + if (!result.Canceled && result.Data is bool and true) + { + await InitializeAsync(); + } + } + + } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Pages/PagesManagementPage.razor b/NetinaShop.AdminPanel.PWA/Pages/PagesManagementPage.razor new file mode 100644 index 0000000..008cba4 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Pages/PagesManagementPage.razor @@ -0,0 +1,95 @@ +@page "/pages" +@attribute [Microsoft.AspNetCore.Authorization.Authorize] + +@inject IDialogService DialogService +@inject NavigationManager NavigationManager +@inject ISnackbar Snackbar +@inject IUserUtility UserUtility +@inject IRestWrapper RestWrapper + + + + + + پرداختـــ ها + + + + + + @* + + *@ + + + + + + + +

@context.Item.Type.ToDisplay()

+
+
+ + + +

@context.Item.Status.ToDisplay()

+
+
+ + + + +

@context.Item.Amount.ToString("N0") ریالــ

+
+
+ + + +

@context.Item.CreatedAt.ToPersianDateTime().ToLongDateString()

+
+
+ + + + + + + + +
+ + + + + + + +
+
+
+
+
+ +@code +{ + public PaymentsPageViewModel ViewModel { get; set; } + protected override async Task OnInitializedAsync() + { + ViewModel = new PaymentsPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService); + await ViewModel.InitializeAsync(); + await base.OnInitializedAsync(); + } +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Pages/PagesManagementPage.razor.cs b/NetinaShop.AdminPanel.PWA/Pages/PagesManagementPage.razor.cs new file mode 100644 index 0000000..299553a --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Pages/PagesManagementPage.razor.cs @@ -0,0 +1,6 @@ +namespace NetinaShop.AdminPanel.PWA.Pages; + +public class PagesManagementPageViewModel +{ + +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor b/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor index 8fb3528..218a7e2 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor @@ -16,34 +16,55 @@ - + @* - + *@ - - - + + + + + + +

@context.Item.Type.ToDisplay()

+
+
+ + + +

@context.Item.Status.ToDisplay()

+
+
+ + + + +

@context.Item.Amount.ToString("N0") ریالــ

+
+
+ + + +

@context.Item.CreatedAt.ToPersianDateTime().ToLongDateString()

+
+
+ - - + OnClick="async()=>await ViewModel.ShowClicked(context.Item)" /> @@ -64,10 +85,10 @@ @code { - public BlogsPageViewModel ViewModel { get; set; } + public PaymentsPageViewModel ViewModel { get; set; } protected override async Task OnInitializedAsync() { - ViewModel = new BlogsPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService); + ViewModel = new PaymentsPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService); await ViewModel.InitializeAsync(); await base.OnInitializedAsync(); } diff --git a/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor.cs b/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor.cs index a87c850..07a8eae 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor.cs +++ b/NetinaShop.AdminPanel.PWA/Pages/PaymentsPage.razor.cs @@ -1,6 +1,105 @@ namespace NetinaShop.AdminPanel.PWA.Pages; -public class PaymentsPageViewModel +public class PaymentsPageViewModel : BaseViewModel> { - + private readonly NavigationManager _navigationManager; + private readonly ISnackbar _snackbar; + private readonly IUserUtility _userUtility; + private readonly IDialogService _dialogService; + private readonly IRestWrapper _restWrapper; + + public string Search = string.Empty; + public int CurrentPage = 0; + public int PageCount = 1; + + public PaymentsPageViewModel(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 + { + var token = await _userUtility.GetBearerTokenAsync(); + if (token == null) + throw new Exception("Token is null"); + IsProcessing = true; + PageDto.Clear(); + var dto = await _restWrapper.PaymentRestApi.ReadAll(CurrentPage, token); + dto.ForEach(d => PageDto.Add(d)); + if (PageDto.Count == 20) + PageCount = 2; + } + 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 ChangePageAsync(int page) + { + CurrentPage = page - 1; + if (CurrentPage > PageCount - 2) + { + + try + { + IsProcessing = true; + var token = await _userUtility.GetBearerTokenAsync(); + if (token == null) + throw new Exception("Token is null"); + + + var dto = await _restWrapper.PaymentRestApi.ReadAll(CurrentPage, token); + dto.ForEach(d => PageDto.Add(d)); + if (PageDto.Count == 20) + PageCount = CurrentPage + 2; + + } + 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; + } + } + } + + + public async Task ShowClicked(PaymentSDto order) + { + //DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, NoHeader = true, FullWidth = true, DisableBackdropClick = true }; + //var parameters = new DialogParameters(); + //parameters.Add(x => x.Order, order); + //var dialogResult = await _dialogService.ShowAsync($" سفارش {order.FactorCode}", parameters, maxWidth); + //var result = await dialogResult.Result; + //if (!result.Canceled && result.Data is bool and true) + //{ + // await InitializeAsync(); + //} + } } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor b/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor index 1ecf0b5..639ec9c 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor @@ -20,6 +20,12 @@ Color="Color.Secondary" OnClick="@ViewModel.AddProductClicked" class="my-auto">افزودن محصول + @* افزودن محصول از دیجیکالا *@ PageDto.Add(d)); + dto.Products.ForEach(d => PageDto.Add(d)); if (PageDto.Count == 20) PageCount = 2; } @@ -61,18 +62,17 @@ public class ProductsPageViewModel : BaseViewModel dto = new List(); + GetProductsResponseDto dto = new GetProductsResponseDto(); if (Search.IsNullOrEmpty()) { - dto = await _restWrapper.CrudDtoApiRest(Address.ProductController) - .ReadAll(CurrentPage); + dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage); } else { dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search); } - dto.ForEach(d => PageDto.Add(d)); + dto.Products.ForEach(d => PageDto.Add(d)); if (PageDto.Count % 20 == 0) PageCount = CurrentPage + 2; @@ -96,7 +96,7 @@ public class ProductsPageViewModel : BaseViewModel("افزودن محصول جدید", maxWidth); var result = await dialogResult.Result; if (!result.Canceled && result.Data is bool and true) @@ -105,9 +105,21 @@ public class ProductsPageViewModel : BaseViewModel("افزودن محصول جدید", maxWidth); + var result = await dialogResult.Result; + if (!result.Canceled && result.Data is bool and true) + { + await InitializeAsync(); + } + } + public async Task EditProductClicked(ProductSDto product) { - DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; + DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, DisableBackdropClick = true }; var parameters = new DialogParameters(); parameters.Add(x => x.Product, product); var dialogResult = await _dialogService.ShowAsync($"ویرایش محصول {product.PersianName}", parameters, maxWidth); @@ -173,7 +185,7 @@ public class ProductsPageViewModel : BaseViewModel PageDto.Add(d)); + dto.Products.ForEach(d => PageDto.Add(d)); if (PageDto.Count == 20) PageCount = 2; } diff --git a/NetinaShop.AdminPanel.PWA/Pages/ShippingPage.razor b/NetinaShop.AdminPanel.PWA/Pages/ShippingPage.razor index cc6286c..a6e17ef 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/ShippingPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/ShippingPage.razor @@ -28,7 +28,13 @@ - + + + +

@context.Item.DeliveryCost.ToString("N0") ریالــ

+
+
+ @if (@context.Item.IsExpressShipping) diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IOrderRestApi.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IOrderRestApi.cs new file mode 100644 index 0000000..954cedc --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IOrderRestApi.cs @@ -0,0 +1,10 @@ +namespace NetinaShop.AdminPanel.PWA.Services.RestServices; + +public interface IOrderRestApi +{ + [Get("")] + Task> ReadAll([Query]int page, [Query] long? selectedDate, [Query] OrderStatus? orderStatus, [Query] OrderQueryDateFilter? dateFilter, [Header("Authorization")] string authorization); + + [Get("/{id}")] + Task ReadOne(Guid id, [Header("Authorization")] string authorization); +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IPageRestApi.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IPageRestApi.cs new file mode 100644 index 0000000..e6b5a81 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IPageRestApi.cs @@ -0,0 +1,14 @@ +namespace NetinaShop.AdminPanel.PWA.Services.RestServices; + +public interface IPageRestApi +{ + + [Get("/type/{type}")] + Task ReadByType([Query] string type, [Header("Authorization")] string authorization); + + [Get("/{id}")] + Task ReadById(Guid id, [Header("Authorization")] string authorization); + + [Post("")] + Task CreatePage([Body] PageActionRequestDto request, [Header("Authorization")] string authorization); +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IPaymentRestApi.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IPaymentRestApi.cs new file mode 100644 index 0000000..bbf3995 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IPaymentRestApi.cs @@ -0,0 +1,8 @@ +namespace NetinaShop.AdminPanel.PWA.Services.RestServices; + +public interface IPaymentRestApi +{ + [Get("")] + Task> ReadAll([Query] int page, [Header("Authorization")] string authorization); + +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IProductRestApi.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IProductRestApi.cs index 7f6356a..07e3d02 100644 --- a/NetinaShop.AdminPanel.PWA/Services/RestServices/IProductRestApi.cs +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IProductRestApi.cs @@ -1,14 +1,18 @@ -namespace NetinaShop.AdminPanel.PWA.Services.RestServices; +using NetinaShop.Domain.Dtos.ResponseDtos; + +namespace NetinaShop.AdminPanel.PWA.Services.RestServices; public interface IProductRestApi { [Get("")] - Task> ReadAll(); + Task ReadAll(); + [Get("/{productId}")] + Task ReadOne(Guid productId); [Get("")] - Task> ReadAll([Query] int page); + Task ReadAll([Query] int page); [Get("")] - Task> ReadAll([Query] int page, [Query] string productName); + Task ReadAll([Query] int page, [Query] string productName); [Get("")] - Task> ReadAll([Query] string productName); + Task ReadAll([Query] string productName); } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs index 6db8b05..f47e3b6 100644 --- a/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs @@ -16,4 +16,8 @@ public interface IRestWrapper public IDiscountRestApi DiscountRest { get; } public IBlogCategoryRestApi BlogCategoryRestApi { get; } public IRoleRestApi RoleRestApi { get; } + public IOrderRestApi OrderRestApi { get; } + public IPaymentRestApi PaymentRestApi { get; } + public IPageRestApi PageRestApi { get; } + public IScraperRestApi ScraperRestApi { get; } } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IScraperRestApi.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IScraperRestApi.cs new file mode 100644 index 0000000..9d6661e --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IScraperRestApi.cs @@ -0,0 +1,11 @@ +using NetinaShop.Domain.Dtos.ScraperDtos.Response; + +namespace NetinaShop.AdminPanel.PWA.Services.RestServices; + +public interface IScraperRestApi +{ + [Get("/digi")] + Task> SearchDigiProductsAsync([Query] string productName, [Header("Authorization")]string authorization); + [Post("/digi/{productId}")] + Task AddDigiProductToShopAsync(string productId, [Query] string productName, [Header("Authorization")] string authorization); +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs index 2b68604..b85353f 100644 --- a/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs @@ -27,5 +27,9 @@ public class RestWrapper : IRestWrapper public IBlogRestApi BlogRestApi => RestService.For(Address.BlogController, setting); public IDiscountRestApi DiscountRest => RestService.For(Address.DiscountController, setting); public IBlogCategoryRestApi BlogCategoryRestApi => RestService.For(Address.BlogCategoryController, setting); - public IRoleRestApi RoleRestApi => RestService.For(Address.RoleController); + public IRoleRestApi RoleRestApi => RestService.For(Address.RoleController, setting); + public IOrderRestApi OrderRestApi => RestService.For(Address.OrderController, setting); + public IPaymentRestApi PaymentRestApi => RestService.For(Address.PaymentController, setting); + public IPageRestApi PageRestApi => RestService.For(Address.PageController, setting); + public IScraperRestApi ScraperRestApi => RestService.For(Address.ScraperController, setting); } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Utilities/Models/CustomEventInterop.cs b/NetinaShop.AdminPanel.PWA/Utilities/Models/CustomEventInterop.cs new file mode 100644 index 0000000..34939f8 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Utilities/Models/CustomEventInterop.cs @@ -0,0 +1,37 @@ +namespace NetinaShop.AdminPanel.PWA.Utilities.Models; + public class CustomEventHelper + { + private readonly Func _callback; + + public CustomEventHelper(Func callback) + { + _callback = callback; + } + + [JSInvokable] + public Task OnCustomEvent(EventArgs args) => _callback(args); + } + + public class CustomEventInterop : IDisposable + { + private readonly IJSRuntime _jsRuntime; + private DotNetObjectReference Reference; + + public CustomEventInterop(IJSRuntime jsRuntime) + { + _jsRuntime = jsRuntime; + } + + public ValueTask SetupCustomEventCallback(Func callback) + { + Reference = DotNetObjectReference.Create(new CustomEventHelper(callback)); + // addCustomEventListener will be a js function we create later + return _jsRuntime.InvokeAsync("addCustomEventListener", Reference); + } + + public void Dispose() + { + Reference?.Dispose(); + } + } + diff --git a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css index 1f84ce6..88bbd4b 100644 --- a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css +++ b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css @@ -1084,6 +1084,10 @@ input:checked + .toggle-bg { margin-top: 2.5rem; margin-bottom: 2.5rem; } +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} .my-4 { margin-top: 1rem; margin-bottom: 1rem; @@ -1128,6 +1132,9 @@ input:checked + .toggle-bg { .mb-5 { margin-bottom: 1.25rem; } +.mb-8 { + margin-bottom: 2rem; +} .mr-1 { margin-right: 0.25rem; } @@ -1158,6 +1165,9 @@ input:checked + .toggle-bg { .mt-6 { margin-top: 1.5rem; } +.mt-8 { + margin-top: 2rem; +} .line-clamp-1 { overflow: hidden; display: -webkit-box; @@ -1224,6 +1234,9 @@ input:checked + .toggle-bg { .h-96 { height: 24rem; } +.h-\[35rem\] { + height: 35rem; +} .h-fit { height: -moz-fit-content; height: fit-content; @@ -1237,6 +1250,9 @@ input:checked + .toggle-bg { .max-h-\[30rem\] { max-height: 30rem; } +.max-h-\[40rem\] { + max-height: 40rem; +} .min-h-\[28rem\] { min-height: 28rem; } @@ -1429,6 +1445,9 @@ input:checked + .toggle-bg { .border-0 { border-width: 0px; } +.border-2 { + border-width: 2px; +} .border-4 { border-width: 4px; } @@ -1441,6 +1460,9 @@ input:checked + .toggle-bg { .border-solid { border-style: solid; } +.border-dashed { + border-style: dashed; +} .border-blue-500 { --tw-border-opacity: 1; border-color: rgb(63 131 248 / var(--tw-border-opacity)); @@ -1469,6 +1491,10 @@ input:checked + .toggle-bg { --tw-border-opacity: 1; border-color: rgb(104 117 245 / var(--tw-border-opacity)); } +.border-violet-400 { + --tw-border-opacity: 1; + border-color: rgb(167 139 250 / var(--tw-border-opacity)); +} .bg-\[\#000000\] { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); @@ -1556,6 +1582,10 @@ input:checked + .toggle-bg { padding-left: 0.5rem; padding-right: 0.5rem; } +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} .px-4 { padding-left: 1rem; padding-right: 1rem; @@ -1572,6 +1602,10 @@ input:checked + .toggle-bg { padding-top: 0.125rem; padding-bottom: 0.125rem; } +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; @@ -1600,6 +1634,9 @@ input:checked + .toggle-bg { .text-justify { text-align: justify; } +.align-bottom { + vertical-align: bottom; +} .text-5xl { font-size: 3rem; } @@ -1673,6 +1710,10 @@ input:checked + .toggle-bg { --tw-text-opacity: 1; color: rgb(225 29 72 / var(--tw-text-opacity)); } +.text-violet-500 { + --tw-text-opacity: 1; + color: rgb(139 92 246 / var(--tw-text-opacity)); +} .text-white { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity)); diff --git a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css index 1329b6f..7536b93 100644 --- a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css +++ b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css @@ -1165,6 +1165,11 @@ input:checked + .toggle-bg { margin-bottom: 2.5rem; } +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} + .my-4 { margin-top: 1rem; margin-bottom: 1rem; @@ -1223,6 +1228,10 @@ input:checked + .toggle-bg { margin-bottom: 1.25rem; } +.mb-8 { + margin-bottom: 2rem; +} + .mr-1 { margin-right: 0.25rem; } @@ -1263,6 +1272,10 @@ input:checked + .toggle-bg { margin-top: 1.5rem; } +.mt-8 { + margin-top: 2rem; +} + .line-clamp-1 { overflow: hidden; display: -webkit-box; @@ -1350,6 +1363,10 @@ input:checked + .toggle-bg { height: 24rem; } +.h-\[35rem\] { + height: 35rem; +} + .h-fit { height: -moz-fit-content; height: fit-content; @@ -1367,6 +1384,10 @@ input:checked + .toggle-bg { max-height: 30rem; } +.max-h-\[40rem\] { + max-height: 40rem; +} + .min-h-\[28rem\] { min-height: 28rem; } @@ -1617,6 +1638,10 @@ input:checked + .toggle-bg { border-width: 0px; } +.border-2 { + border-width: 2px; +} + .border-4 { border-width: 4px; } @@ -1633,6 +1658,10 @@ input:checked + .toggle-bg { border-style: solid; } +.border-dashed { + border-style: dashed; +} + .border-blue-500 { --tw-border-opacity: 1; border-color: rgb(63 131 248 / var(--tw-border-opacity)); @@ -1668,6 +1697,11 @@ input:checked + .toggle-bg { border-color: rgb(104 117 245 / var(--tw-border-opacity)); } +.border-violet-400 { + --tw-border-opacity: 1; + border-color: rgb(167 139 250 / var(--tw-border-opacity)); +} + .bg-\[\#000000\] { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); @@ -1780,6 +1814,11 @@ input:checked + .toggle-bg { padding-right: 0.5rem; } +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + .px-4 { padding-left: 1rem; padding-right: 1rem; @@ -1800,6 +1839,11 @@ input:checked + .toggle-bg { padding-bottom: 0.125rem; } +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; @@ -1836,6 +1880,10 @@ input:checked + .toggle-bg { text-align: justify; } +.align-bottom { + vertical-align: bottom; +} + .text-5xl { font-size: 3rem; } @@ -1930,6 +1978,11 @@ input:checked + .toggle-bg { color: rgb(225 29 72 / var(--tw-text-opacity)); } +.text-violet-500 { + --tw-text-opacity: 1; + color: rgb(139 92 246 / var(--tw-text-opacity)); +} + .text-white { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity)); diff --git a/NetinaShop.AdminPanel.PWA/wwwroot/service-worker.published.js b/NetinaShop.AdminPanel.PWA/wwwroot/service-worker.published.js index 1f7f543..604c401 100644 --- a/NetinaShop.AdminPanel.PWA/wwwroot/service-worker.published.js +++ b/NetinaShop.AdminPanel.PWA/wwwroot/service-worker.published.js @@ -5,7 +5,9 @@ self.importScripts('./service-worker-assets.js'); self.addEventListener('install', event => event.waitUntil(onInstall(event))); self.addEventListener('activate', event => event.waitUntil(onActivate(event))); self.addEventListener('fetch', event => event.respondWith(onFetch(event))); - +self.addEventListener('message', event => { + if (event.data?.type === 'SKIP_WAITING') self.skipWaiting(); +}); const cacheNamePrefix = 'offline-cache-'; const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];