feat : add version 0.6.12.22 , fix updating issue
complete discount and product page changingrelease
							parent
							
								
									f883451697
								
							
						
					
					
						commit
						e6dd4c875e
					
				|  | @ -2,6 +2,7 @@ | ||||||
|            Color="@Color" |            Color="@Color" | ||||||
|            @onclick="OnClickCallback" |            @onclick="OnClickCallback" | ||||||
|            @attributes="CapturedAttributes" |            @attributes="CapturedAttributes" | ||||||
|  |            Size="Size" | ||||||
|            Disabled="IsProcessing" |            Disabled="IsProcessing" | ||||||
|            DisableElevation="true" |            DisableElevation="true" | ||||||
|            > |            > | ||||||
|  | @ -47,6 +48,9 @@ | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public bool IsProcessing { get; set; } = false; |     public bool IsProcessing { get; set; } = false; | ||||||
| 
 | 
 | ||||||
|  |     [Parameter] | ||||||
|  |     public Size Size { get; set; } = Size.Medium; | ||||||
|  | 
 | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public EventCallback OnClickCallback { get; set; } |     public EventCallback OnClickCallback { get; set; } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,25 +1,36 @@ | ||||||
| @inject IJSRuntime JsRuntime | @inject IJSRuntime JsRuntime | ||||||
|  | @implements IAsyncDisposable | ||||||
| 
 | 
 | ||||||
| <div class="editor"></div> | <div class="editor"></div> | ||||||
| 
 | 
 | ||||||
| <script type="text/javascript"> | <script type="text/javascript"> | ||||||
|     function destroyEditor() { |     function destroyEditor() { | ||||||
|         window.editor?.destroy() |         // document.querySelector('.editor').ckeditorInstance.destroy(); | ||||||
|  |         window.editor = null; | ||||||
|  |         console.log('Editor Destroyed'); | ||||||
|     } |     } | ||||||
|     function lunchEditor(data) { |     function lunchEditor(data) { | ||||||
|         |         if (!document.querySelector('.editor')) return | ||||||
|  |         if (window.editor) return | ||||||
|         ClassicEditor.create(document.querySelector('.editor'), { |         ClassicEditor.create(document.querySelector('.editor'), { | ||||||
|                 // Editor configuration. |                 // Editor configuration. | ||||||
|             }) |             }) | ||||||
|             .then(editor => { |             .then(editor => { | ||||||
|                 window.editor = editor; |                 window.editor = editor; | ||||||
|                 window.editor.setData(data); |                 window.editor.setData(data); | ||||||
|                 editor.on('change', function () { |                 editor.editing.view.document.on('blur', () => { | ||||||
|                     console.log(editor.getData()); |                     GLOBAL.DotNetReference.invokeMethodAsync('MyMethod',window.editor.getData()); | ||||||
|                 }); |                 }); | ||||||
|             }) |             }) | ||||||
|             .catch(handleSampleError); |             .catch(handleSampleError); | ||||||
|     } |     } | ||||||
|  |     var GLOBAL = {}; | ||||||
|  |     GLOBAL.DotNetReference = null; | ||||||
|  |     GLOBAL.SetDotnetReference = function (pDotNetReference) { | ||||||
|  |         GLOBAL.DotNetReference = pDotNetReference; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     function handleSampleError(error) { |     function handleSampleError(error) { | ||||||
|         const issueUrl = 'https://github.com/ckeditor/ckeditor5/issues'; |         const issueUrl = 'https://github.com/ckeditor/ckeditor5/issues'; | ||||||
| 
 | 
 | ||||||
|  | @ -44,6 +55,15 @@ | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public EventCallback<string> TextChanged { get; set; } |     public EventCallback<string> TextChanged { get; set; } | ||||||
| 
 | 
 | ||||||
|  |     [JSInvokable("MyMethod")] | ||||||
|  |     public void HandleEditorBlur(string data) | ||||||
|  |     { | ||||||
|  |         Text = data; | ||||||
|  |         TextChanged.InvokeAsync(data); | ||||||
|  |         StateHasChanged(); // Ensure UI updates | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     protected override Task OnParametersSetAsync() |     protected override Task OnParametersSetAsync() | ||||||
|     { |     { | ||||||
|         return base.OnParametersSetAsync(); |         return base.OnParametersSetAsync(); | ||||||
|  | @ -51,8 +71,23 @@ | ||||||
| 
 | 
 | ||||||
|     protected override async Task OnAfterRenderAsync(bool firstRender) |     protected override async Task OnAfterRenderAsync(bool firstRender) | ||||||
|     { |     { | ||||||
|  |          | ||||||
|  |         var lDotNetReference = DotNetObjectReference.Create(this); | ||||||
|  |         await JsRuntime.InvokeVoidAsync("GLOBAL.SetDotnetReference", lDotNetReference); | ||||||
|  | 
 | ||||||
|         await JsRuntime.InvokeVoidAsync("window.lunchEditor", Text); |         await JsRuntime.InvokeVoidAsync("window.lunchEditor", Text); | ||||||
|         await base.OnAfterRenderAsync(firstRender); |         await base.OnAfterRenderAsync(firstRender); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void Dispose() | ||||||
|  |     { | ||||||
|  |         JsRuntime.InvokeVoidAsync("window.destroyEditor", Text); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public async ValueTask DisposeAsync() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         await JsRuntime.InvokeVoidAsync("window.destroyEditor", Text); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -71,6 +71,11 @@ | ||||||
|         </MudNavGroup> |         </MudNavGroup> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |         <MudNavGroup Title="فروشگاه من" Expanded="false" | ||||||
|  |                      Icon="@Icons.Material.Outlined.Settings"> | ||||||
|  | 
 | ||||||
|  |             <MudNavLink Href="faqs" Icon="@Icons.Material.Filled.ManageAccounts">سوالات متداول</MudNavLink> | ||||||
|  |         </MudNavGroup> | ||||||
| 
 | 
 | ||||||
|         <MudNavGroup Title="تنظیماتـــ" Expanded="false" |         <MudNavGroup Title="تنظیماتـــ" Expanded="false" | ||||||
|                      Icon="@Icons.Material.Outlined.Settings"> |                      Icon="@Icons.Material.Outlined.Settings"> | ||||||
|  | @ -78,12 +83,13 @@ | ||||||
|             <MudNavLink Href="users" Icon="@Icons.Material.Filled.ManageAccounts">نقش ها و کاربران</MudNavLink> |             <MudNavLink Href="users" Icon="@Icons.Material.Filled.ManageAccounts">نقش ها و کاربران</MudNavLink> | ||||||
|         </MudNavGroup> |         </MudNavGroup> | ||||||
|     </MudNavMenu> |     </MudNavMenu> | ||||||
| 
 |     <p class="bottom-0 align-bottom mx-auto">Version : @version</p> | ||||||
| </MudStack> | </MudStack> | ||||||
| 
 | 
 | ||||||
| @code | @code | ||||||
| { | { | ||||||
|      |      | ||||||
|  |     string? version = typeof(Program)?.Assembly.GetName()?.Version?.ToString(); | ||||||
|     private void SelectNav() |     private void SelectNav() | ||||||
|     { |     { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,89 @@ | ||||||
|  | @using NetinaShop.Domain.Entities.Users | ||||||
|  | 
 | ||||||
|  | @inject ISnackbar Snackbar | ||||||
|  | @inject IRestWrapper RestWrapper | ||||||
|  | @inject IUserUtility UserUtility | ||||||
|  | @inject IDialogService DialogService | ||||||
|  | 
 | ||||||
|  | <MudDialog DisableSidePadding="true" class="mx-auto"> | ||||||
|  |     <DialogContent> | ||||||
|  |         <MudStack class="px-4"> | ||||||
|  |             <MudDivider class="-mt-3" /> | ||||||
|  |             <MudStack Spacing="0"> | ||||||
|  | 
 | ||||||
|  |                 <MudText Typo="Typo.h6"><b>جست جو از دیجیکالا</b></MudText> | ||||||
|  |                 <MudText Typo="Typo.caption">میتوانید نام کالا را از دیجیکالا جست جو کرده و به فروشگاه اضافه کنید</MudText> | ||||||
|  |             </MudStack> | ||||||
|  | 
 | ||||||
|  |             <MudTextField T="string" Placeholder="جست جو بر اساس نام" Adornment="Adornment.Start" Immediate="true" | ||||||
|  |                           Clearable="true" | ||||||
|  |                           Variant="Variant.Outlined" | ||||||
|  |                           ValueChanged="@ViewModel.SearchChanged" | ||||||
|  |                           AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto" | ||||||
|  |                           OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField> | ||||||
|  | 
 | ||||||
|  |             <MudContainer class="h-[35rem]" Style="overflow-y: scroll"> | ||||||
|  |                 @if (ViewModel.IsProcessing) | ||||||
|  |                 { | ||||||
|  |                     <MudProgressCircular class="my-auto" Size="Size.Large" Color="Color.Info" Indeterminate="true" /> | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     @foreach (var item in ViewModel.PageDto) | ||||||
|  |                     { | ||||||
|  |                         <MudCard Outlined="true" class="my-2"> | ||||||
|  |                             <MudCardContent> | ||||||
|  |                                 <MudStack Row="true"> | ||||||
|  |                                     <MudImage Width="100" Height="100" Class="rounded-lg" Src="@item.MainImage" /> | ||||||
|  |                                     <MudStack> | ||||||
|  |                                         <MudText Typo="Typo.body1">@item.PersianName</MudText> | ||||||
|  |                                             <MudText Typo="Typo.body1">@item.EnglishName</MudText> | ||||||
|  |                                             <MudText Typo="Typo.body2">@item.Summery</MudText> | ||||||
|  |                                             <MudText Typo="Typo.body2">قیمت : @item.Cost.ToString("N0")</MudText> | ||||||
|  |                                         </MudStack> | ||||||
|  |                                     </MudStack> | ||||||
|  |                                 </MudCardContent> | ||||||
|  |                                 <MudCardActions> | ||||||
|  |                                     <MudButton OnClick="async()=> await ViewModel.AddProductToShopAsync(item.ScraperId)" | ||||||
|  |                                                Variant="Variant.Outlined" | ||||||
|  |                                                Color="Color.Success">افزودن به فروشگاه</MudButton> | ||||||
|  |                                     <a href="@item.ScraperUrl" target="_blank"> | ||||||
|  |                                         <MudButton class="mx-3" | ||||||
|  |                                                    Variant="Variant.Outlined" | ||||||
|  |                                                    Color="Color.Warning">مشاهده کالا</MudButton> | ||||||
|  |                                     </a> | ||||||
|  |                                 </MudCardActions> | ||||||
|  |                             </MudCard> | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             </MudContainer> | ||||||
|  |         </MudStack> | ||||||
|  |     </DialogContent> | ||||||
|  |     <DialogActions> | ||||||
|  |         <MudStack Row="true" class="w-full mx-4 mb-2"> | ||||||
|  | 
 | ||||||
|  |             @* <BaseButtonUi class="w-64 rounded-md" IsProcessing="@ViewModel.IsProcessing" | ||||||
|  |             Icon="@Icons.Material.Outlined.Check" | ||||||
|  |             Variant="Variant.Filled" Color="Color.Success" | ||||||
|  |             Content="ثبت ویرایش" OnClickCallback="@ViewModel.SubmitEditAsync" /> *@ | ||||||
|  |             <MudSpacer /> | ||||||
|  |             <MudButton Variant="Variant.Outlined" Size="Size.Large" Color="Color.Error" OnClick="@ViewModel.Cancel">بستن</MudButton> | ||||||
|  |         </MudStack> | ||||||
|  |     </DialogActions> | ||||||
|  | </MudDialog> | ||||||
|  | @code { | ||||||
|  | 
 | ||||||
|  |     [CascadingParameter] | ||||||
|  |     MudDialogInstance MudDialog { get; set; } | ||||||
|  | 
 | ||||||
|  |     public DigikalaProductActionDialogBoxViewModel ViewModel { get; set; } | ||||||
|  | 
 | ||||||
|  |     protected override async Task OnInitializedAsync() | ||||||
|  |     { | ||||||
|  |         ViewModel = new DigikalaProductActionDialogBoxViewModel(Snackbar, RestWrapper, UserUtility, DialogService, MudDialog); | ||||||
|  |         await ViewModel.InitializeAsync(); | ||||||
|  |         await base.OnInitializedAsync(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,101 @@ | ||||||
|  | using NetinaShop.Domain.Dtos.ScraperDtos.Response; | ||||||
|  | 
 | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Dialogs; | ||||||
|  | 
 | ||||||
|  | public class DigikalaProductActionDialogBoxViewModel : BaseViewModel<ObservableCollection<ScraperProductDto>> | ||||||
|  | { | ||||||
|  |     private readonly ISnackbar _snackbar; | ||||||
|  |     private readonly IRestWrapper _restWrapper; | ||||||
|  |     private readonly IUserUtility _userUtility; | ||||||
|  |     private readonly IDialogService _dialogService; | ||||||
|  |     private readonly MudDialogInstance _mudDialog; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public string Search = string.Empty; | ||||||
|  | 
 | ||||||
|  |     public DigikalaProductActionDialogBoxViewModel(ISnackbar snackbar, | ||||||
|  |         IRestWrapper restWrapper, | ||||||
|  |         IUserUtility userUtility, | ||||||
|  |         IDialogService dialogService, | ||||||
|  |         MudDialogInstance mudDialog) | ||||||
|  |     { | ||||||
|  |         _snackbar = snackbar; | ||||||
|  |         _restWrapper = restWrapper; | ||||||
|  |         _userUtility = userUtility; | ||||||
|  |         _dialogService = dialogService; | ||||||
|  |         _mudDialog = mudDialog; | ||||||
|  |     } | ||||||
|  |     public void Cancel() => _mudDialog.Cancel(); | ||||||
|  | 
 | ||||||
|  |     public async Task AddProductToShopAsync(string productId) | ||||||
|  |     { | ||||||
|  |         var options = new DialogOptions { CloseOnEscapeKey = true }; | ||||||
|  |         var parameters = new DialogParameters<QuestionDialog>(); | ||||||
|  |         parameters.Add(x => x.ContentText, "آیا از افزودن محصول اطمینان دارید ?"); | ||||||
|  |         var dialogReference = await _dialogService.ShowAsync<QuestionDialog>("افزودن محصول از دیجیکالا", parameters, options); | ||||||
|  |         var result = await dialogReference.Result; | ||||||
|  |         if (!result.Canceled) | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 var token = await _userUtility.GetBearerTokenAsync(); | ||||||
|  |                 if (token == null) | ||||||
|  |                     throw new Exception("Token is null"); | ||||||
|  |                 IsProcessing = true; | ||||||
|  |                 await _restWrapper.ScraperRestApi.AddDigiProductToShopAsync(productId,Search, token); | ||||||
|  |                 _snackbar.Add("کالا افزوده شد", Severity.Success); | ||||||
|  |             } | ||||||
|  |             catch (ApiException ex) | ||||||
|  |             { | ||||||
|  |                 var exe = await ex.GetContentAsAsync<ApiResult>(); | ||||||
|  |                 _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 SearchChanged(string search) | ||||||
|  |     { | ||||||
|  |         if (search.IsNullOrEmpty() && !Search.IsNullOrEmpty()) | ||||||
|  |             await InitializeAsync(); | ||||||
|  |         Search = search; | ||||||
|  |     } | ||||||
|  |     public async Task SearchAsync() | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             var token = await _userUtility.GetBearerTokenAsync(); | ||||||
|  |             if (token == null) | ||||||
|  |                 throw new Exception("Token is null"); | ||||||
|  |             if (Search.IsNullOrEmpty()) | ||||||
|  |                 throw new AppException("اسم کالا برای جست جو وارد نشده است"); | ||||||
|  |             IsProcessing = true; | ||||||
|  |             var dto = await _restWrapper.ScraperRestApi.SearchDigiProductsAsync(Search, token); | ||||||
|  |             PageDto.Clear(); | ||||||
|  |             dto.ForEach(d => PageDto.Add(d)); | ||||||
|  |         } | ||||||
|  |         catch (ApiException ex) | ||||||
|  |         { | ||||||
|  |             var exe = await ex.GetContentAsAsync<ApiResult>(); | ||||||
|  |             _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); | ||||||
|  |         } | ||||||
|  |         catch (Exception e) | ||||||
|  |         { | ||||||
|  |             _snackbar.Add(e.Message, Severity.Error); | ||||||
|  |         } | ||||||
|  |         finally | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             IsProcessing = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| using Mapster; | using Mapster; | ||||||
|  | using NetinaShop.Domain.Dtos.ResponseDtos; | ||||||
| using NetinaShop.Domain.Entities.Blogs; | using NetinaShop.Domain.Entities.Blogs; | ||||||
| using NetinaShop.Domain.Entities.Discounts; | using NetinaShop.Domain.Entities.Discounts; | ||||||
| using NetinaShop.Domain.Mappers; | using NetinaShop.Domain.Mappers; | ||||||
|  | @ -230,15 +231,33 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto> | ||||||
|         { |         { | ||||||
|             IsProcessing = true; |             IsProcessing = true; | ||||||
|             if (_discountId == default) |             if (_discountId == default) | ||||||
|                 throw new Exception("بلاگ اشتباه است"); |                 throw new Exception("Id is null"); | ||||||
|  | 
 | ||||||
|  |             if (IsAllEnable) | ||||||
|  |             { | ||||||
|  |                 PageDto.Type = DiscountType.All; | ||||||
|  |             } | ||||||
|  |             else if (IsCategoryEnable) | ||||||
|  |             { | ||||||
|  |                 PageDto.Type = DiscountType.Category; | ||||||
|                 if (SelectedCategory == null) |                 if (SelectedCategory == null) | ||||||
|                 throw new Exception("لطفا یک دسته بندی انتخاب کنید"); |                     throw new Exception("دسته بندی را برای تخفیف انتخاب نمایید"); | ||||||
|  |                 PageDto.CategoryId = SelectedCategory.Id; | ||||||
|  |             } | ||||||
|  |             else if (IsProductEnable) | ||||||
|  |             { | ||||||
|  |                 PageDto.Type = DiscountType.Product; | ||||||
|  |                 if (SelectedProduct == null) | ||||||
|  |                     throw new Exception("کالا مورد نظر را برای تخفیف انتخاب نمایید"); | ||||||
|  |                 PageDto.ProductId = SelectedProduct.Id; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             var token = await _userUtility.GetBearerTokenAsync(); |             var token = await _userUtility.GetBearerTokenAsync(); | ||||||
|             if (token == null) |             if (token == null) | ||||||
|                 throw new Exception("Token is null"); |                 throw new Exception("Token is null"); | ||||||
|             PageDto.Id = _discountId; |             PageDto.Id = _discountId; | ||||||
|             var request = PageDto.Adapt<UpdateDiscountCommand>(); |             var request = PageDto.Adapt<UpdateDiscountCommand>(); | ||||||
|             await _restWrapper.CrudApiRest<Discount, Guid>(Address.DiscountController).Create<UpdateDiscountCommand>(request, token); |             await _restWrapper.CrudApiRest<Discount, Guid>(Address.DiscountController).Update<UpdateDiscountCommand>(request, token); | ||||||
|             _snackbar.Add($"ویرایش تخفیف با موفقیت انجام شد", Severity.Success); |             _snackbar.Add($"ویرایش تخفیف با موفقیت انجام شد", Severity.Success); | ||||||
|             _mudDialog.Close(); |             _mudDialog.Close(); | ||||||
|         } |         } | ||||||
|  | @ -298,10 +317,12 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto> | ||||||
|     { |     { | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|  |             GetProductsResponseDto response = new GetProductsResponseDto(); | ||||||
|             if (product.IsNullOrEmpty()) |             if (product.IsNullOrEmpty()) | ||||||
|                 _products = await _restWrapper.ProductRestApi.ReadAll(0); |                 response = await _restWrapper.ProductRestApi.ReadAll(0); | ||||||
|             else |             else | ||||||
|                 _products = await _restWrapper.ProductRestApi.ReadAll(product); |                 response = await _restWrapper.ProductRestApi.ReadAll(product); | ||||||
|  |             _products = response.Products; | ||||||
|             return _products; |             return _products; | ||||||
|         } |         } | ||||||
|         catch (ApiException ex) |         catch (ApiException ex) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,219 @@ | ||||||
|  | @inject ISnackbar Snackbar | ||||||
|  | @inject IRestWrapper RestWrapper | ||||||
|  | @inject IUserUtility UserUtility | ||||||
|  | @inject IDialogService DialogService | ||||||
|  | 
 | ||||||
|  | <MudDialog class="mx-auto" DisableSidePadding="true"> | ||||||
|  |     <DialogContent> | ||||||
|  |         <MudContainer class="max-h-[40rem] mt-4" Style="overflow-y: scroll"> | ||||||
|  |             <MudGrid> | ||||||
|  |                 <MudItem md="9"> | ||||||
|  |                     <MudStack> | ||||||
|  |                          | ||||||
|  |                         <MudStack Row="true"> | ||||||
|  |                              | ||||||
|  |                             <MudText Typo="Typo.h6" class="my-auto"><b>اطلاعات سفارش</b></MudText> | ||||||
|  |                             <MudSpacer/> | ||||||
|  |                             <MudPaper Elevation="0" class="bg-blue-500 px-4 py-2 my-auto"> | ||||||
|  |                                 <MudText Typo="Typo.body2" class="text-white">@ViewModel.PageDto.OrderStatus.ToDisplay()</MudText> | ||||||
|  |                             </MudPaper> | ||||||
|  |                         </MudStack> | ||||||
|  | 
 | ||||||
|  |                         <MudGrid> | ||||||
|  |                             <MudItem sm="4"> | ||||||
|  |                                 <MudField Variant="Variant.Outlined" Label="نام و نام خانوادگی">@ViewModel.PageDto.UserFullName</MudField> | ||||||
|  |                             </MudItem> | ||||||
|  | 
 | ||||||
|  |                             <MudItem sm="4"> | ||||||
|  |                                 <MudField Variant="Variant.Outlined" Label="شماره تماس">@ViewModel.PageDto.UserPhoneNumber</MudField> | ||||||
|  |                             </MudItem> | ||||||
|  | 
 | ||||||
|  |                             <MudItem sm="4"> | ||||||
|  |                                 <MudField Variant="Variant.Outlined" Label="کد تخفیف">@ViewModel.PageDto.DiscountCode</MudField> | ||||||
|  |                             </MudItem> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                             <MudItem sm="9"> | ||||||
|  |                                 <MudField Variant="Variant.Outlined" Label="آدرس">@ViewModel.PageDto.OrderDelivery.Address</MudField> | ||||||
|  |                             </MudItem> | ||||||
|  |                             <MudItem sm="3"> | ||||||
|  |                                 <MudField Variant="Variant.Outlined" Label="روش ارسال">@ViewModel.PageDto.OrderDelivery.ShippingMethod</MudField> | ||||||
|  |                             </MudItem> | ||||||
|  |                         </MudGrid> | ||||||
|  |                          | ||||||
|  |                             <MudStack class="mt-3" Row="true"> | ||||||
|  |                              | ||||||
|  |                                 <MudText Typo="Typo.h6"><b>کالاهای این سفارش</b></MudText> | ||||||
|  |                                 <MudSpacer/> | ||||||
|  |                             <MudPaper Elevation="0" class="border-dashed border-violet-400 border-2 px-3 py-1 my-auto"> | ||||||
|  |                                     <MudText Typo="Typo.caption" class="text-violet-500"><b>@ViewModel.PageDto.OrderProducts.Sum(op => op.Count) قلم کالا</b></MudText> | ||||||
|  |                             </MudPaper> | ||||||
|  |                         </MudStack> | ||||||
|  | 
 | ||||||
|  |                             <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" | ||||||
|  |                                          Elevation="0" | ||||||
|  |                                          Bordered="true" | ||||||
|  |                                          T="OrderProductSDto" Items="@ViewModel.PageDto.OrderProducts" | ||||||
|  |                                          Filterable="false" Loading="@ViewModel.IsProcessing" | ||||||
|  |                                          SortMode="@SortMode.None" Groupable="false" | ||||||
|  |                                          class="border-solid border-2 border-gray-200"> | ||||||
|  |                                 <Columns> | ||||||
|  | 
 | ||||||
|  |                                     <TemplateColumn T="OrderProductSDto" Title="نام کالا"> | ||||||
|  | 
 | ||||||
|  |                                         <CellTemplate> | ||||||
|  |                                             <b>@context.Item.ProductName</b> | ||||||
|  |                                     </CellTemplate> | ||||||
|  |                                 </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                                 <TemplateColumn T="OrderProductSDto" Title="قیمت کالا"> | ||||||
|  | 
 | ||||||
|  |                                     <CellTemplate> | ||||||
|  |                                         <p>@context.Item.ProductFeeWithDiscount.ToString("N0") ریالــ</p> | ||||||
|  |                                     </CellTemplate> | ||||||
|  |                                 </TemplateColumn> | ||||||
|  |                                 <PropertyColumn Title="تعداد" Property="arg => arg.Count" /> | ||||||
|  | 
 | ||||||
|  |                                 <TemplateColumn T="OrderProductSDto" Title="قیمت کل"> | ||||||
|  | 
 | ||||||
|  |                                     <CellTemplate> | ||||||
|  |                                         <p>@context.Item.ProductCost.ToString("N0") ریالــ</p> | ||||||
|  |                                     </CellTemplate> | ||||||
|  |                                 </TemplateColumn> | ||||||
|  |                             </Columns> | ||||||
|  |                         </MudDataGrid> | ||||||
|  | 
 | ||||||
|  |                     </MudStack> | ||||||
|  |                 </MudItem> | ||||||
|  | 
 | ||||||
|  |                 <MudItem md="3"> | ||||||
|  | 
 | ||||||
|  |                     <MudText Typo="Typo.h6" class="mb-2"><b>مبــــالغ</b></MudText> | ||||||
|  |                     <MudPaper class="bg-[--mud-palette-background-grey] rounded-md"> | ||||||
|  |                         <MudStack class="p-3"> | ||||||
|  | 
 | ||||||
|  |                             <MudStack Row="true"> | ||||||
|  |                                 <MudText class="my-auto" Typo="Typo.body2">جمع کالاها : </MudText> | ||||||
|  |                                 <MudSpacer/> | ||||||
|  |                                 <MudText Typo="Typo.body1"><b>@ViewModel.PageDto.TotalProductsPrice.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                             </MudStack> | ||||||
|  | 
 | ||||||
|  |                             <MudDivider/> | ||||||
|  | 
 | ||||||
|  |                             <MudStack Row="true"> | ||||||
|  |                                 <MudText class="my-auto" Typo="Typo.body2">مالیات : </MudText> | ||||||
|  |                                 <MudSpacer/> | ||||||
|  |                                 <MudText Typo="Typo.body1"><b>@ViewModel.PageDto.TaxesPrice.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                             </MudStack> | ||||||
|  | 
 | ||||||
|  |                             <MudDivider/> | ||||||
|  | 
 | ||||||
|  |                             <MudStack Row="true"> | ||||||
|  |                                 <MudText class="my-auto" Typo="Typo.body2">بسته بندی : </MudText> | ||||||
|  |                                 <MudSpacer/> | ||||||
|  |                                 <MudText Typo="Typo.body1"><b>@ViewModel.PageDto.PackingPrice.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                             </MudStack> | ||||||
|  | 
 | ||||||
|  |                             <MudDivider/> | ||||||
|  | 
 | ||||||
|  |                             <MudStack Row="true"> | ||||||
|  |                                 <MudText class="my-auto" Typo="Typo.body2">هزینه ارسال : </MudText> | ||||||
|  |                                 <MudSpacer/> | ||||||
|  |                                 <MudText Typo="Typo.body1"><b>@ViewModel.PageDto.DeliveryPrice.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                             </MudStack> | ||||||
|  | 
 | ||||||
|  |                         </MudStack> | ||||||
|  | 
 | ||||||
|  |                         <MudPaper class="mud-theme-dark rounded-md"> | ||||||
|  | 
 | ||||||
|  |                             <MudStack class="p-3"> | ||||||
|  | 
 | ||||||
|  |                                 <MudStack Row="true"> | ||||||
|  |                                     <MudText class="my-auto" Typo="Typo.body2">جمع کل : </MudText> | ||||||
|  |                                     <MudSpacer/> | ||||||
|  |                                     <MudText Typo="Typo.body1"><b>@ViewModel.PageDto.TotalPriceWithoutDiscount.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                                 </MudStack> | ||||||
|  | 
 | ||||||
|  |                                 <MudDivider/> | ||||||
|  | 
 | ||||||
|  |                                 <MudStack Row="true"> | ||||||
|  |                                     <MudText class="my-auto" Typo="Typo.body2">مقدار تخفیف : </MudText> | ||||||
|  |                                     <MudSpacer/> | ||||||
|  |                                     <MudText Typo="Typo.body1"><b>@ViewModel.PageDto.DiscountPrice.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                                 </MudStack> | ||||||
|  | 
 | ||||||
|  |                                 <MudDivider/> | ||||||
|  | 
 | ||||||
|  |                                 <MudStack Row="true"> | ||||||
|  |                                     <MudText class="my-auto" Typo="Typo.body2">مبلغ قابل پرداخت : </MudText> | ||||||
|  |                                     <MudSpacer/> | ||||||
|  |                                     <MudText Typo="Typo.body1"><b>@ViewModel.PageDto.TotalPrice.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                                 </MudStack> | ||||||
|  | 
 | ||||||
|  |                             </MudStack> | ||||||
|  |                         </MudPaper> | ||||||
|  |                     </MudPaper> | ||||||
|  | 
 | ||||||
|  |                     <MudText Typo="Typo.h6" class="mt-3"><b>پرداختــ ها</b></MudText> | ||||||
|  |                      | ||||||
|  |                     <MudPaper Elevation="0" class="bg-[--mud-palette-background-grey] rounded-md"> | ||||||
|  |                     <MudStack class="p-3"> | ||||||
|  |                          | ||||||
|  |                         @foreach (var item in ViewModel.PageDto.Payments) | ||||||
|  |                         { | ||||||
|  |                             <MudStack Row="true"> | ||||||
|  |                                 <MudText class="my-auto" Typo="Typo.body2">@item.Type.ToDisplay()</MudText> | ||||||
|  |                                 <MudSpacer/> | ||||||
|  |                                 <MudText Typo="Typo.body1"><b>@item.Amount.ToString("N0")</b> ریالــ</MudText> | ||||||
|  |                             </MudStack> | ||||||
|  |                         } | ||||||
|  |                          | ||||||
|  |                     </MudStack> | ||||||
|  |                     </MudPaper> | ||||||
|  |                 </MudItem> | ||||||
|  |             </MudGrid> | ||||||
|  |         </MudContainer> | ||||||
|  |     </DialogContent> | ||||||
|  |     <DialogActions> | ||||||
|  |         <MudStack Row="true" class="w-full h-fit mx-4 mb-3 bottom-0"> | ||||||
|  |              | ||||||
|  |             <BaseButtonUi class="w-64 h-12 rounded-md" IsProcessing="@ViewModel.IsProcessing" | ||||||
|  |                           Icon="@Icons.Material.Outlined.AirportShuttle" | ||||||
|  |                           Variant="Variant.Filled" Color="Color.Success" | ||||||
|  |                           Content="ثبت ارسال سفارش" OnClickCallback="ViewModel.SubmitEditAsync" /> | ||||||
|  |             <BaseButtonUi class="w-52 h-12 rounded-md" IsProcessing="@ViewModel.IsProcessing" | ||||||
|  |                           Icon="@Icons.Material.Outlined.RemoveCircle" | ||||||
|  |                           Variant="Variant.Outlined" Color="Color.Error" | ||||||
|  |                           Content="لغو سفارش" OnClickCallback="ViewModel.SubmitEditAsync" /> | ||||||
|  |             <MudSpacer /> | ||||||
|  | 
 | ||||||
|  |             <BaseButtonUi class="w-52 h-12 rounded-md my-auto" IsProcessing="@ViewModel.IsProcessing" | ||||||
|  |                           Icon="@Icons.Material.Outlined.Print" | ||||||
|  |                           Size="Size.Small" | ||||||
|  |                           Variant="Variant.Outlined" Color="Color.Info" | ||||||
|  |                           Content="چاپــ فاکتور" OnClickCallback="ViewModel.SubmitEditAsync" /> | ||||||
|  |             <MudButton Variant="Variant.Outlined" Size="Size.Medium" Color="Color.Error" OnClick="ViewModel.Cancel">بستن</MudButton> | ||||||
|  |         </MudStack> | ||||||
|  |     </DialogActions> | ||||||
|  | </MudDialog> | ||||||
|  | 
 | ||||||
|  | @code { | ||||||
|  | 
 | ||||||
|  |     [CascadingParameter] | ||||||
|  |     MudDialogInstance MudDialog { get; set; } | ||||||
|  | 
 | ||||||
|  |     [Parameter] | ||||||
|  |     public OrderSDto? Order { get; set; } | ||||||
|  | 
 | ||||||
|  |     public OrderActionDialogBoxViewModel ViewModel { get; set; } | ||||||
|  | 
 | ||||||
|  |     protected override async Task OnInitializedAsync() | ||||||
|  |     { | ||||||
|  |         if (Order == null) | ||||||
|  |             ViewModel = new OrderActionDialogBoxViewModel(Snackbar, RestWrapper, UserUtility, DialogService, MudDialog); | ||||||
|  |         else | ||||||
|  |             ViewModel = new OrderActionDialogBoxViewModel(Snackbar, RestWrapper, UserUtility, DialogService, MudDialog, Order); | ||||||
|  |         await ViewModel.InitializeAsync(); | ||||||
|  |         await base.OnInitializedAsync(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,106 @@ | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Dialogs; | ||||||
|  | 
 | ||||||
|  | public class OrderActionDialogBoxViewModel : BaseViewModel<OrderLDto> | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     private readonly ISnackbar _snackbar; | ||||||
|  |     private readonly IRestWrapper _restWrapper; | ||||||
|  |     private readonly IUserUtility _userUtility; | ||||||
|  |     private readonly IDialogService _dialogService; | ||||||
|  |     private readonly MudDialogInstance _mudDialog; | ||||||
|  | 
 | ||||||
|  |     public OrderActionDialogBoxViewModel(ISnackbar snackbar, IRestWrapper restWrapper, IUserUtility userUtility, IDialogService dialogService, MudDialogInstance mudDialog) | ||||||
|  |     { | ||||||
|  |         _snackbar = snackbar; | ||||||
|  |         _restWrapper = restWrapper; | ||||||
|  |         _userUtility = userUtility; | ||||||
|  |         _dialogService = dialogService; | ||||||
|  |         _mudDialog = mudDialog; | ||||||
|  |     } | ||||||
|  |     public OrderActionDialogBoxViewModel(ISnackbar snackbar, | ||||||
|  |         IRestWrapper restWrapper, | ||||||
|  |         IUserUtility userUtility, | ||||||
|  |         IDialogService dialogService, | ||||||
|  |         MudDialogInstance mudDialog, | ||||||
|  |         OrderSDto order) | ||||||
|  |     { | ||||||
|  |         _snackbar = snackbar; | ||||||
|  |         _restWrapper = restWrapper; | ||||||
|  |         _userUtility = userUtility; | ||||||
|  |         _dialogService = dialogService; | ||||||
|  |         _mudDialog = mudDialog; | ||||||
|  |         PageDto.Id = order.Id; | ||||||
|  |         IsEditing = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public void Cancel() => _mudDialog.Cancel(); | ||||||
|  | 
 | ||||||
|  |     public bool IsEditing = false; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public override async Task InitializeAsync() | ||||||
|  |     { | ||||||
|  |         if (IsEditing && PageDto.Id != default) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  | 
 | ||||||
|  |                 var token = await _userUtility.GetBearerTokenAsync(); | ||||||
|  |                 if (token == null) | ||||||
|  |                     throw new Exception("Token is null"); | ||||||
|  | 
 | ||||||
|  |                 IsProcessing = true; | ||||||
|  | 
 | ||||||
|  |                 var order = await _restWrapper.OrderRestApi.ReadOne(PageDto.Id, token); | ||||||
|  |                 PageDto = order; | ||||||
|  |             } | ||||||
|  |             catch (ApiException ex) | ||||||
|  |             { | ||||||
|  |                 var exe = await ex.GetContentAsAsync<ApiResult>(); | ||||||
|  |                 if (exe != null) | ||||||
|  |                     _snackbar.Add(exe.Message, Severity.Error); | ||||||
|  |                 _snackbar.Add(ex.Content, Severity.Error); | ||||||
|  |                 _mudDialog.Cancel(); | ||||||
|  |             } | ||||||
|  |             catch (Exception e) | ||||||
|  |             { | ||||||
|  |                 _snackbar.Add(e.Message, Severity.Error); | ||||||
|  |                 _mudDialog.Cancel(); | ||||||
|  |             } | ||||||
|  |             finally | ||||||
|  |             { | ||||||
|  | 
 | ||||||
|  |                 IsProcessing = false; | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public async Task SubmitEditAsync() | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             IsProcessing = true; | ||||||
|  |             _snackbar.Add($"ویرایش سفارش {PageDto.FactorCode} با موفقیت انجام شد", Severity.Success); | ||||||
|  |             _mudDialog.Close(); | ||||||
|  |         } | ||||||
|  |         catch (ApiException ex) | ||||||
|  |         { | ||||||
|  |             var exe = await ex.GetContentAsAsync<ApiResult>(); | ||||||
|  |             if (exe != null) | ||||||
|  |                 _snackbar.Add(exe.Message, Severity.Error); | ||||||
|  |             _snackbar.Add(ex.Content, Severity.Error); | ||||||
|  |             _mudDialog.Cancel(); | ||||||
|  |         } | ||||||
|  |         catch (Exception e) | ||||||
|  |         { | ||||||
|  |             _snackbar.Add(e.Message, Severity.Error); | ||||||
|  |             _mudDialog.Cancel(); | ||||||
|  |         } | ||||||
|  |         finally | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             IsProcessing = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,14 +1,10 @@ | ||||||
| @using Radzen.Blazor | @using NetinaShop.AdminPanel.PWA.Extensions | ||||||
| @using NetinaShop.AdminPanel.PWA.Extensions |  | ||||||
| 
 | 
 | ||||||
| @inject ISnackbar Snackbar | @inject ISnackbar Snackbar | ||||||
| @inject IRestWrapper RestWrapper | @inject IRestWrapper RestWrapper | ||||||
| @inject IUserUtility UserUtility | @inject IUserUtility UserUtility | ||||||
| @inject IDialogService DialogService | @inject IDialogService DialogService | ||||||
| 
 | 
 | ||||||
| <head> |  | ||||||
|     <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> |  | ||||||
| </head> |  | ||||||
| 
 | 
 | ||||||
| <MudDialog class="mx-auto"> | <MudDialog class="mx-auto"> | ||||||
| <DialogContent> | <DialogContent> | ||||||
|  | @ -177,42 +173,6 @@ | ||||||
|             </MudItem> |             </MudItem> | ||||||
|         </MudGrid> |         </MudGrid> | ||||||
|     </div> |     </div> | ||||||
|      |  | ||||||
|     <script type="text/javascript"> |  | ||||||
|          |  | ||||||
|          |  | ||||||
|   |  | ||||||
|                var myInterval = setInterval(()=>{ |  | ||||||
|                    lunchEditor() |  | ||||||
|                    console.log("retry to load editor") |  | ||||||
|                },50) |  | ||||||
|         |  | ||||||
|         function lunchEditor() { |  | ||||||
|                             if (document.querySelector('.editor')) { |  | ||||||
|                                 ClassicEditor |  | ||||||
|                                     .create(document.querySelector('.editor'), { |  | ||||||
|                                         // Editor configuration. |  | ||||||
|                                     }) |  | ||||||
|                                     .then(editor => { |  | ||||||
|                                         window.editor = editor; |  | ||||||
|                                         clearInterval(myInterval) |  | ||||||
|                                         console.info("Editor Lunched , Interval Cleared !") |  | ||||||
|                                     }) |  | ||||||
|                                     .catch(handleSampleError); |  | ||||||
|                             }else return |  | ||||||
|         } |  | ||||||
|         function handleSampleError(error) { |  | ||||||
|             const issueUrl = 'https://github.com/ckeditor/ckeditor5/issues'; |  | ||||||
| 
 |  | ||||||
|             const message = [ |  | ||||||
|                 'Oops, something went wrong!', |  | ||||||
|                 `Please, report the following error on ${issueUrl} with the build id "pws0dnpd0jqj-zi42lsl7aqxa" and the error stack trace:` |  | ||||||
|             ].join('\n'); |  | ||||||
| 
 |  | ||||||
|             console.error(message); |  | ||||||
|             console.error(error); |  | ||||||
|         } |  | ||||||
|     </script> |  | ||||||
| </MudTabPanel> | </MudTabPanel> | ||||||
| <MudTabPanel Text="تـــــصاویر" Icon="@Icons.Material.Outlined.ImageSearch"> | <MudTabPanel Text="تـــــصاویر" Icon="@Icons.Material.Outlined.ImageSearch"> | ||||||
| 
 | 
 | ||||||
|  | @ -307,7 +267,7 @@ | ||||||
| </MudContainer> | </MudContainer> | ||||||
| </DialogContent> | </DialogContent> | ||||||
| <DialogActions> | <DialogActions> | ||||||
|     <MudStack Row="true" class="w-full h-fit mx-4 bottom-0"> |     <MudStack Row="true" class="w-full h-fit mx-4 mb-3 bottom-0"> | ||||||
| 
 | 
 | ||||||
|         @if (ViewModel.IsEditing) |         @if (ViewModel.IsEditing) | ||||||
|         { |         { | ||||||
|  |  | ||||||
|  | @ -80,7 +80,8 @@ public class ProductActionDialogBoxViewModel : BaseViewModel<ProductLDto> | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|                 IsProcessing = true; |                 IsProcessing = true; | ||||||
|                 var productLDto = await _restWrapper.CrudDtoApiRest<Product, ProductLDto, Guid>(Address.ProductController).ReadOne(_product.Id); |                 var response = await _restWrapper.ProductRestApi.ReadOne(_product.Id); | ||||||
|  |                 var productLDto = response.Product; | ||||||
|                 PageDto.ExpertCheck = productLDto.ExpertCheck; |                 PageDto.ExpertCheck = productLDto.ExpertCheck; | ||||||
|                 PageDto.Summery = productLDto.Summery; |                 PageDto.Summery = productLDto.Summery; | ||||||
|                 PageDto.BeDisplayed = productLDto.BeDisplayed; |                 PageDto.BeDisplayed = productLDto.BeDisplayed; | ||||||
|  |  | ||||||
|  | @ -40,8 +40,8 @@ | ||||||
| 
 | 
 | ||||||
|             <MudLayout> |             <MudLayout> | ||||||
|                 <MudAppBar class="py-2" Color="Color.Transparent" Fixed="false" Elevation="2"> |                 <MudAppBar class="py-2" Color="Color.Transparent" Fixed="false" Elevation="2"> | ||||||
|                     <MudHidden Breakpoint="Breakpoint.SmAndUp"> |                     <MudHidden Breakpoint="Breakpoint.MdAndUp"> | ||||||
|                         <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" /> |                         <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" OnClick="@ToggleDrawer" Edge="Edge.Start" /> | ||||||
|                     </MudHidden> |                     </MudHidden> | ||||||
|                     @* <MudAvatar Size="Size.Large" Variant="Variant.Outlined"> |                     @* <MudAvatar Size="Size.Large" Variant="Variant.Outlined"> | ||||||
|                         <MudImage Src="https://img.freepik.com/free-photo/portrait-white-man-isolated_53876-40306.jpg?size=626&ext=jpg&ga=GA1.1.632798143.1705708800&semt=ais"></MudImage> |                         <MudImage Src="https://img.freepik.com/free-photo/portrait-white-man-isolated_53876-40306.jpg?size=626&ext=jpg&ga=GA1.1.632798143.1705708800&semt=ais"></MudImage> | ||||||
|  | @ -53,14 +53,18 @@ | ||||||
|                         <MudText Color="Color.Inherit" Typo="Typo.caption">@_user?.PhoneNumber</MudText> |                         <MudText Color="Color.Inherit" Typo="Typo.caption">@_user?.PhoneNumber</MudText> | ||||||
|                     </MudStack> |                     </MudStack> | ||||||
|                     <MudSpacer /> |                     <MudSpacer /> | ||||||
|                     <MudIconButton Size="Size.Medium" Color="Color.Inherit" Icon="@Icons.Material.Outlined.Settings"/> |                     @* <MudIconButton Size="Size.Medium" Color="Color.Inherit" Icon="@Icons.Material.Outlined.Settings"/> *@ | ||||||
|                     <MudIconButton Size="Size.Medium" Color="Color.Error" OnClick="LogoutAsync" Icon="@Icons.Material.Outlined.ExitToApp" /> |                     <MudIconButton Size="Size.Medium" Color="Color.Error" OnClick="LogoutAsync" Icon="@Icons.Material.Outlined.ExitToApp" /> | ||||||
|                 </MudAppBar> |                 </MudAppBar> | ||||||
|                  |                  | ||||||
|  |                     <MudDrawer @bind-Open="@open" Breakpoint="Breakpoint.MdAndUp" Elevation="1" Variant="@DrawerVariant.Responsive"> | ||||||
|  |                     <SideBarUi/> | ||||||
|  |                 </MudDrawer> | ||||||
|  | 
 | ||||||
|                 <MudGrid Spacing="0"> |                 <MudGrid Spacing="0"> | ||||||
| 
 | 
 | ||||||
|                     <MudItem sm="0" md="3" lg="2"> |                     <MudItem sm="0" md="3" lg="2"> | ||||||
|                         <MudHidden Breakpoint="Breakpoint.SmAndDown"> |                         <MudHidden Breakpoint="Breakpoint.MdAndDown"> | ||||||
|                             <SideBarUi/> |                             <SideBarUi/> | ||||||
|                         </MudHidden> |                         </MudHidden> | ||||||
|                     </MudItem> |                     </MudItem> | ||||||
|  | @ -73,7 +77,7 @@ | ||||||
|                 </MudGrid> |                 </MudGrid> | ||||||
|             </MudLayout> |             </MudLayout> | ||||||
|             <div dir="ltr"> |             <div dir="ltr"> | ||||||
|                 <PWAUpdater StateChanged="Callback"  Text="@_updateText" ButtonCaption="اپدیت کنید"/> |                 <PWAUpdater Align="PWAUpdater.Aligns.Buttom" Text="@_updateText" ButtonCaption="اپدیت کنید"/> | ||||||
|             </div> |             </div> | ||||||
|         </MudRTLProvider> |         </MudRTLProvider> | ||||||
|          |          | ||||||
|  | @ -101,6 +105,8 @@ | ||||||
| 
 | 
 | ||||||
|     private string _updateText = "! نسخه جدید پنل ادمین رسید"; |     private string _updateText = "! نسخه جدید پنل ادمین رسید"; | ||||||
|     private ApplicationUserSDto? _user; |     private ApplicationUserSDto? _user; | ||||||
|  |     bool open = false; | ||||||
|  |     void ToggleDrawer() => open = !open; | ||||||
|     private async Task LogoutAsync() |     private async Task LogoutAsync() | ||||||
|     { |     { | ||||||
|         await UserUtility.LogoutAsync(); |         await UserUtility.LogoutAsync(); | ||||||
|  | @ -118,11 +124,6 @@ | ||||||
|     protected override async Task OnInitializedAsync() |     protected override async Task OnInitializedAsync() | ||||||
|     { |     { | ||||||
|         _user = await UserUtility.GetUserAsync(); |         _user = await UserUtility.GetUserAsync(); | ||||||
| 
 |  | ||||||
|         await base.OnInitializedAsync(); |         await base.OnInitializedAsync(); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     private void Callback(PWAUpdater.States obj) |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,4 +19,8 @@ public static class Address | ||||||
|     public static string DiscountController => $"{BaseAddress}/discount"; |     public static string DiscountController => $"{BaseAddress}/discount"; | ||||||
|     public static string RoleController => $"{BaseAddress}/user/role"; |     public static string RoleController => $"{BaseAddress}/user/role"; | ||||||
|     public static string ShippingController => $"{BaseAddress}/warehouse/shipping"; |     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"; | ||||||
| } | } | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Models; | ||||||
|  | 
 | ||||||
|  | // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(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<OrderProduct> OrderProducts { get; set; } | ||||||
|  |     public List<object> OrderDeliveries { get; set; } | ||||||
|  |     public string Id { get; set; } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -5,8 +5,9 @@ | ||||||
|     <Nullable>enable</Nullable> |     <Nullable>enable</Nullable> | ||||||
|     <ImplicitUsings>enable</ImplicitUsings> |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|     <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest> |     <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest> | ||||||
|     <AssemblyVersion>0.4.3.12</AssemblyVersion> |     <AssemblyVersion>0.6.12.22</AssemblyVersion> | ||||||
|     <FileVersion>0.4.3.12</FileVersion> |     <FileVersion>0.6.12.22</FileVersion> | ||||||
|  |     <AssemblyName>$(MSBuildProjectName)</AssemblyName> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
| 
 | 
 | ||||||
| 	<Target Name="PostBuild" AfterTargets="PostBuildEvent"> | 	<Target Name="PostBuild" AfterTargets="PostBuildEvent"> | ||||||
|  | @ -38,10 +39,6 @@ | ||||||
|     <ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" /> |     <ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| 
 | 
 | ||||||
|   <ItemGroup> |  | ||||||
|     <Folder Include="Utilities\" /> |  | ||||||
|   </ItemGroup> |  | ||||||
| 
 |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Using Include="Blazored.LocalStorage" /> |     <Using Include="Blazored.LocalStorage" /> | ||||||
|     <Using Include="Microsoft.AspNetCore.Components" /> |     <Using Include="Microsoft.AspNetCore.Components" /> | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  | 
 | ||||||
|  | <MudStack class="w-full p-8 h-screen bg-[--mud-palette-background-grey]"> | ||||||
|  |     <MudGrid> | ||||||
|  |         <MudItem xs="12"> | ||||||
|  |             <MudStack Row="true" class="mb-8"> | ||||||
|  |                 <MudText Typo="Typo.h4">سوالات متداول فروشگاه من</MudText> | ||||||
|  |                 <MudSpacer /> | ||||||
|  |                 <MudButton Variant="Variant.Outlined" Size="Size.Large" Color="Color.Success" OnClick="@ViewModel.SaveAsync">ذخیره سوالات</MudButton> | ||||||
|  |             </MudStack> | ||||||
|  |             <MudGrid> | ||||||
|  |                 <MudItem sm="4"> | ||||||
|  |                     <MudTextField T="string" Label="سوال" @bind-Value="@ViewModel.Question" Variant="Variant.Outlined"></MudTextField> | ||||||
|  |                 </MudItem> | ||||||
|  |                 <MudItem sm="6"> | ||||||
|  |                     <MudTextField T="string" Label="پاسخ" @bind-Value="@ViewModel.Answer" Variant="Variant.Outlined"></MudTextField> | ||||||
|  |                 </MudItem> | ||||||
|  |                 <MudItem sm="1"> | ||||||
|  |                     <MudButton class="my-auto" EndIcon="@Icons.Material.Outlined.Add"  | ||||||
|  |                                Variant="Variant.Outlined" Size="Size.Large" Color="Color.Info" OnClick="@ViewModel.AddNewQuestion">افزودن</MudButton> | ||||||
|  |                 </MudItem> | ||||||
|  |             </MudGrid> | ||||||
|  |             <MudPaper> | ||||||
|  |                 <MudExpansionPanels class="mt-8"> | ||||||
|  |                     @foreach (var item in ViewModel.PageDto.Faqs) | ||||||
|  |                     { | ||||||
|  |                         <MudExpansionPanel> | ||||||
|  | 
 | ||||||
|  |                             <TitleContent> | ||||||
|  |                                 <MudStack Row="true"> | ||||||
|  |                                     <MudIconButton Icon="@Icons.Material.Outlined.Delete" | ||||||
|  |                                                    Size="@Size.Small" | ||||||
|  |                                                    Variant="@Variant.Outlined" | ||||||
|  |                                                    Color="@Color.Error" | ||||||
|  |                                                    OnClick="()=>ViewModel.RemoveQuestion(item.Key)" /> | ||||||
|  |                                     <MudText>@item.Key</MudText> | ||||||
|  |                                     </MudStack> | ||||||
|  |                                 </TitleContent> | ||||||
|  |                                 <ChildContent> | ||||||
|  |                                     @item.Value | ||||||
|  |                             </ChildContent> | ||||||
|  |                         </MudExpansionPanel> | ||||||
|  |                     } | ||||||
|  |                 </MudExpansionPanels> | ||||||
|  |             </MudPaper> | ||||||
|  |         </MudItem> | ||||||
|  |     </MudGrid> | ||||||
|  | </MudStack> | ||||||
|  | 
 | ||||||
|  | @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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,139 @@ | ||||||
|  | using NetinaShop.Domain.Entities.Pages; | ||||||
|  | 
 | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Pages; | ||||||
|  | 
 | ||||||
|  | public class FaqManagementPageViewModel : BaseViewModel<FAQPage> | ||||||
|  | { | ||||||
|  |     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<FAQPage>(); | ||||||
|  |                 _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<ApiResult>(); | ||||||
|  |             _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<ApiResult>(); | ||||||
|  |             _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); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -44,34 +44,53 @@ | ||||||
|              |              | ||||||
|             <MudPaper> |             <MudPaper> | ||||||
|                 <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" |                 <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" | ||||||
|                              T="BlogSDto" Items="@ViewModel.PageDto" CurrentPage="@ViewModel.CurrentPage" |                              T="OrderSDto" Items="@ViewModel.MainOrders" CurrentPage="@ViewModel.MainGridCurrentPage" | ||||||
|                              RowsPerPage="20" Filterable="false" Loading="@ViewModel.IsProcessing" |                              RowsPerPage="20" Filterable="false" Loading="@ViewModel.IsProcessing" | ||||||
|                              SortMode="@SortMode.None" Groupable="false"> |                              SortMode="@SortMode.None" Groupable="false"> | ||||||
| 
 | 
 | ||||||
|                     <ToolBarContent> |                     <ToolBarContent> | ||||||
|                         <MudTextField T="string" Placeholder="جست جو بر اساس کد پیگیری" Adornment="Adornment.Start" Immediate="true" |                         @* <MudTextField T="string" Placeholder="جست جو بر اساس کد پیگیری" Adornment="Adornment.Start" Immediate="true" | ||||||
|                                       Clearable="true" |                                       Clearable="true" | ||||||
|                                       ValueChanged="@ViewModel.SearchChanged" |                                       ValueChanged="@ViewModel.SearchChanged" | ||||||
|                                       AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto" |                                       AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto" | ||||||
|                                       OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField> |                                       OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField> *@ | ||||||
|                     </ToolBarContent> |                     </ToolBarContent> | ||||||
|                     <Columns> |                     <Columns> | ||||||
|                         <PropertyColumn Title="کد پیگیری" Property="arg => arg.Title"/> |                         <PropertyColumn Title="کد سفارش" Property="arg => arg.FactorCode" /> | ||||||
|                         <PropertyColumn Title="مبلغ" Property="arg => arg.CategoryName"/> |                         <PropertyColumn Title="نام خریدار" Property="arg => arg.UserFullName" /> | ||||||
|                         <PropertyColumn Title="تاریخ پرداخت" Property="arg => arg.ReadingTime"/> |                         <TemplateColumn T="OrderSDto" Title="تاریخ سفارش"> | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.OrderAt.ToPersianDateTime().ToLongDateString()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                         <TemplateColumn T="OrderSDto" Title="تاریخ پرداخت"> | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.PayedAt.ToPersianDateTime().ToLongDateString()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                         <TemplateColumn T="OrderSDto" Title="مبلغ سفارش "> | ||||||
|  |                              | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.TotalPrice.ToString("N0") ریالــ</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  |                         <TemplateColumn T="OrderSDto" Title="وضعیت سفارش"> | ||||||
|  | 
 | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.OrderStatus.ToDisplay()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  |                          | ||||||
|                         <TemplateColumn CellClass="d-flex justify-end"> |                         <TemplateColumn CellClass="d-flex justify-end"> | ||||||
|                             <CellTemplate> |                             <CellTemplate> | ||||||
|                                 <MudStack Row="true"> |                                 <MudStack Row="true"> | ||||||
|                                     <MudIconButton Icon="@Icons.Material.Filled.Edit" |                                     <MudIconButton Icon="@Icons.Material.Filled.RemoveRedEye" | ||||||
|                                                    Size="@Size.Small" |                                                    Size="@Size.Small" | ||||||
|                                                    Variant="@Variant.Outlined" |                                                    Variant="@Variant.Outlined" | ||||||
|                                                    Color="@Color.Info" |                                                    Color="@Color.Info" | ||||||
|                                                    OnClick="async () => await ViewModel.EditBlogClicked(context.Item)"/> |                                                    OnClick="async () => await ViewModel.ShowClicked(context.Item)"/> | ||||||
|                                     <MudIconButton Icon="@Icons.Material.Filled.Delete" |  | ||||||
|                                                    Size="@Size.Small" |  | ||||||
|                                                    Variant="@Variant.Outlined" |  | ||||||
|                                                    OnClick="async () => await ViewModel.DeleteBlogAsync(context.Item.Id)" |  | ||||||
|                                                    Color="@Color.Error"/> |  | ||||||
|                                 </MudStack> |                                 </MudStack> | ||||||
|                             </CellTemplate> |                             </CellTemplate> | ||||||
|                         </TemplateColumn> |                         </TemplateColumn> | ||||||
|  | @ -79,7 +98,7 @@ | ||||||
|                     <PagerContent> |                     <PagerContent> | ||||||
|                         <MudStack Row="true" class="w-full"> |                         <MudStack Row="true" class="w-full"> | ||||||
| 
 | 
 | ||||||
|                             <MudPagination Rectangular="true" Variant="Variant.Filled" Count="@ViewModel.PageCount" |                             <MudPagination Rectangular="true" Variant="Variant.Filled" Count="@ViewModel.MainGridPageCount" | ||||||
|                                            SelectedChanged="@ViewModel.ChangePageAsync" class="my-4 mx-auto"/> |                                            SelectedChanged="@ViewModel.ChangePageAsync" class="my-4 mx-auto"/> | ||||||
|                         </MudStack> |                         </MudStack> | ||||||
| 
 | 
 | ||||||
|  | @ -92,10 +111,10 @@ | ||||||
| 
 | 
 | ||||||
| @code | @code | ||||||
| { | { | ||||||
|     public BlogsPageViewModel ViewModel { get; set; } |     public OrdersPageViewModel ViewModel { get; set; } | ||||||
|     protected override async Task OnInitializedAsync() |     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 ViewModel.InitializeAsync(); | ||||||
|         await base.OnInitializedAsync(); |         await base.OnInitializedAsync(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,109 @@ | ||||||
| namespace NetinaShop.AdminPanel.PWA.Pages; | 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<OrderSDto> MainOrders { get; } = new ObservableCollection<OrderSDto>(); | ||||||
|  | 
 | ||||||
|  |     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<ApiResult>(); | ||||||
|  |             _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<ApiResult>(); | ||||||
|  |                 _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<OrderActionDialogBox>(); | ||||||
|  |         parameters.Add(x => x.Order, order); | ||||||
|  |         var dialogResult = await _dialogService.ShowAsync<OrderActionDialogBox>($" سفارش {order.FactorCode}", parameters, maxWidth); | ||||||
|  |         var result = await dialogResult.Result; | ||||||
|  |         if (!result.Canceled && result.Data is bool and true) | ||||||
|  |         { | ||||||
|  |             await InitializeAsync(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | @ -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 | ||||||
|  | 
 | ||||||
|  | <MudStack class="w-full p-8 h-screen bg-[--mud-palette-background-grey]"> | ||||||
|  |     <MudGrid> | ||||||
|  |         <MudItem xs="12"> | ||||||
|  |             <MudStack Row="true" class="mb-5"> | ||||||
|  |                 <MudText Typo="Typo.h4">پرداختـــ ها</MudText> | ||||||
|  |                 <MudSpacer /> | ||||||
|  |             </MudStack> | ||||||
|  |             <MudPaper> | ||||||
|  |                 <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" | ||||||
|  |                              T="PaymentSDto" Items="@ViewModel.PageDto" CurrentPage="@ViewModel.CurrentPage" | ||||||
|  |                              RowsPerPage="20" Filterable="false" Loading="@ViewModel.IsProcessing" | ||||||
|  |                              SortMode="@SortMode.None" Groupable="false"> | ||||||
|  | 
 | ||||||
|  |                     @* <ToolBarContent> | ||||||
|  |                     <MudTextField T="string" Placeholder="جست جو بر اساس کد پیگیری" Adornment="Adornment.Start" Immediate="true" | ||||||
|  |                     Clearable="true" | ||||||
|  |                     ValueChanged="@ViewModel.SearchChanged" | ||||||
|  |                     AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto" | ||||||
|  |                     OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField> | ||||||
|  |                     </ToolBarContent> *@ | ||||||
|  |                     <Columns> | ||||||
|  |                         <PropertyColumn Title="شماره فاکتور" Property="arg => arg.FactorNumber" /> | ||||||
|  |                         <PropertyColumn Title="پرداخت کننده" Property="arg => arg.UserFullName" /> | ||||||
|  |                         <PropertyColumn Title="شماره تماس" Property="arg => arg.UserPhoneNumber" /> | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="نوع پرداخت"> | ||||||
|  | 
 | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.Type.ToDisplay()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="وظعیت پرداخت"> | ||||||
|  | 
 | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.Status.ToDisplay()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="مبلغ سفارش "> | ||||||
|  | 
 | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.Amount.ToString("N0") ریالــ</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="تاریخ پرداخت"> | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.CreatedAt.ToPersianDateTime().ToLongDateString()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                         <TemplateColumn CellClass="d-flex justify-end"> | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <MudStack Row="true"> | ||||||
|  |                                     <MudIconButton Icon="@Icons.Material.Filled.PanoramaFishEye" | ||||||
|  |                                                    Size="@Size.Small" | ||||||
|  |                                                    Variant="@Variant.Outlined" | ||||||
|  |                                                    Color="@Color.Info" | ||||||
|  |                                                    OnClick="async()=>await ViewModel.ShowClicked(context.Item)" /> | ||||||
|  |                                 </MudStack> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  |                     </Columns> | ||||||
|  |                     <PagerContent> | ||||||
|  |                         <MudStack Row="true" class="w-full"> | ||||||
|  | 
 | ||||||
|  |                             <MudPagination Rectangular="true" Variant="Variant.Filled" Count="@ViewModel.PageCount" | ||||||
|  |                                            SelectedChanged="@ViewModel.ChangePageAsync" class="my-4 mx-auto" /> | ||||||
|  |                         </MudStack> | ||||||
|  | 
 | ||||||
|  |                     </PagerContent> | ||||||
|  |                 </MudDataGrid> | ||||||
|  |             </MudPaper> | ||||||
|  |         </MudItem> | ||||||
|  |     </MudGrid> | ||||||
|  | </MudStack> | ||||||
|  | 
 | ||||||
|  | @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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,6 @@ | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Pages; | ||||||
|  | 
 | ||||||
|  | public class PagesManagementPageViewModel | ||||||
|  | { | ||||||
|  |      | ||||||
|  | } | ||||||
|  | @ -16,34 +16,55 @@ | ||||||
|             </MudStack> |             </MudStack> | ||||||
|             <MudPaper> |             <MudPaper> | ||||||
|                 <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" |                 <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" | ||||||
|                              T="BlogSDto" Items="@ViewModel.PageDto" CurrentPage="@ViewModel.CurrentPage" |                              T="PaymentSDto" Items="@ViewModel.PageDto" CurrentPage="@ViewModel.CurrentPage" | ||||||
|                              RowsPerPage="20" Filterable="false" Loading="@ViewModel.IsProcessing" |                              RowsPerPage="20" Filterable="false" Loading="@ViewModel.IsProcessing" | ||||||
|                              SortMode="@SortMode.None" Groupable="false"> |                              SortMode="@SortMode.None" Groupable="false"> | ||||||
| 
 | 
 | ||||||
|                     <ToolBarContent> |                     @* <ToolBarContent> | ||||||
|                         <MudTextField T="string" Placeholder="جست جو بر اساس کد پیگیری" Adornment="Adornment.Start" Immediate="true" |                         <MudTextField T="string" Placeholder="جست جو بر اساس کد پیگیری" Adornment="Adornment.Start" Immediate="true" | ||||||
|                                       Clearable="true" |                                       Clearable="true" | ||||||
|                                       ValueChanged="@ViewModel.SearchChanged" |                                       ValueChanged="@ViewModel.SearchChanged" | ||||||
|                                       AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto" |                                       AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto" | ||||||
|                                       OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField> |                                       OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField> | ||||||
|                     </ToolBarContent> |                     </ToolBarContent> *@ | ||||||
|                     <Columns> |                     <Columns> | ||||||
|                         <PropertyColumn Title="کد پیگیری" Property="arg => arg.Title" /> |                         <PropertyColumn Title="شماره فاکتور" Property="arg => arg.FactorNumber" /> | ||||||
|                         <PropertyColumn Title="مبلغ" Property="arg => arg.CategoryName" /> |                         <PropertyColumn Title="پرداخت کننده" Property="arg => arg.UserFullName" /> | ||||||
|                         <PropertyColumn Title="تاریخ پرداخت" Property="arg => arg.ReadingTime" /> |                         <PropertyColumn Title="شماره تماس" Property="arg => arg.UserPhoneNumber" /> | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="نوع پرداخت"> | ||||||
|  | 
 | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.Type.ToDisplay()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="وظعیت پرداخت"> | ||||||
|  | 
 | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.Status.ToDisplay()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="مبلغ سفارش "> | ||||||
|  | 
 | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.Amount.ToString("N0") ریالــ</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|  |                         <TemplateColumn T="PaymentSDto" Title="تاریخ پرداخت"> | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.CreatedAt.ToPersianDateTime().ToLongDateString()</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|                         <TemplateColumn CellClass="d-flex justify-end"> |                         <TemplateColumn CellClass="d-flex justify-end"> | ||||||
|                             <CellTemplate> |                             <CellTemplate> | ||||||
|                                 <MudStack Row="true"> |                                 <MudStack Row="true"> | ||||||
|                                     <MudIconButton Icon="@Icons.Material.Filled.Edit" |                                     <MudIconButton Icon="@Icons.Material.Filled.PanoramaFishEye" | ||||||
|                                                    Size="@Size.Small" |                                                    Size="@Size.Small" | ||||||
|                                                    Variant="@Variant.Outlined" |                                                    Variant="@Variant.Outlined" | ||||||
|                                                    Color="@Color.Info" |                                                    Color="@Color.Info" | ||||||
|                                                    OnClick="async()=>await ViewModel.EditBlogClicked(context.Item)" /> |                                                    OnClick="async()=>await ViewModel.ShowClicked(context.Item)" /> | ||||||
|                                     <MudIconButton Icon="@Icons.Material.Filled.Delete" |  | ||||||
|                                                    Size="@Size.Small" |  | ||||||
|                                                    Variant="@Variant.Outlined" |  | ||||||
|                                                    OnClick="async () => await ViewModel.DeleteBlogAsync(context.Item.Id)" |  | ||||||
|                                                    Color="@Color.Error" /> |  | ||||||
|                                 </MudStack> |                                 </MudStack> | ||||||
|                             </CellTemplate> |                             </CellTemplate> | ||||||
|                         </TemplateColumn> |                         </TemplateColumn> | ||||||
|  | @ -64,10 +85,10 @@ | ||||||
| 
 | 
 | ||||||
| @code | @code | ||||||
| { | { | ||||||
|     public BlogsPageViewModel ViewModel { get; set; } |     public PaymentsPageViewModel ViewModel { get; set; } | ||||||
|     protected override async Task OnInitializedAsync() |     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 ViewModel.InitializeAsync(); | ||||||
|         await base.OnInitializedAsync(); |         await base.OnInitializedAsync(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,105 @@ | ||||||
| namespace NetinaShop.AdminPanel.PWA.Pages; | namespace NetinaShop.AdminPanel.PWA.Pages; | ||||||
| 
 | 
 | ||||||
| public class PaymentsPageViewModel | public class PaymentsPageViewModel : BaseViewModel<ObservableCollection<PaymentSDto>> | ||||||
|  | { | ||||||
|  |     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<ApiResult>(); | ||||||
|  |             _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<ApiResult>(); | ||||||
|  |                 _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<OrderActionDialogBox>(); | ||||||
|  |         //parameters.Add(x => x.Order, order); | ||||||
|  |         //var dialogResult = await _dialogService.ShowAsync<OrderActionDialogBox>($" سفارش {order.FactorCode}", parameters, maxWidth); | ||||||
|  |         //var result = await dialogResult.Result; | ||||||
|  |         //if (!result.Canceled && result.Data is bool and true) | ||||||
|  |         //{ | ||||||
|  |         //    await InitializeAsync(); | ||||||
|  |         //} | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -20,6 +20,12 @@ | ||||||
|                            Color="Color.Secondary"  |                            Color="Color.Secondary"  | ||||||
|                            OnClick="@ViewModel.AddProductClicked" |                            OnClick="@ViewModel.AddProductClicked" | ||||||
|                            class="my-auto">افزودن محصول</MudButton> |                            class="my-auto">افزودن محصول</MudButton> | ||||||
|  |                 @* <MudButton Variant="Variant.Filled" | ||||||
|  |                            DisableElevation="true" | ||||||
|  |                            StartIcon="@Icons.Material.Outlined.Add" | ||||||
|  |                            Color="Color.Error" | ||||||
|  |                            OnClick="@ViewModel.AddDigikalaProductClicked" | ||||||
|  |                            class="my-auto">افزودن محصول از دیجیکالا</MudButton> *@ | ||||||
|             </MudStack> |             </MudStack> | ||||||
|             <MudPaper> |             <MudPaper> | ||||||
|                 <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" |                 <MudDataGrid FixedFooter="true" FixedHeader="true" Striped="true" | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| using MudBlazor; | using MudBlazor; | ||||||
|  | using NetinaShop.Domain.Dtos.ResponseDtos; | ||||||
| 
 | 
 | ||||||
| namespace NetinaShop.AdminPanel.PWA.Pages; | namespace NetinaShop.AdminPanel.PWA.Pages; | ||||||
| 
 | 
 | ||||||
|  | @ -30,7 +31,7 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS | ||||||
|             IsProcessing = true; |             IsProcessing = true; | ||||||
|             PageDto.Clear(); |             PageDto.Clear(); | ||||||
|             var dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage); |             var dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage); | ||||||
|             dto.ForEach(d => PageDto.Add(d)); |             dto.Products.ForEach(d => PageDto.Add(d)); | ||||||
|             if (PageDto.Count == 20) |             if (PageDto.Count == 20) | ||||||
|                 PageCount = 2; |                 PageCount = 2; | ||||||
|         } |         } | ||||||
|  | @ -61,18 +62,17 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS | ||||||
|             { |             { | ||||||
|                 IsProcessing = true; |                 IsProcessing = true; | ||||||
| 
 | 
 | ||||||
|                 List<ProductSDto> dto = new List<ProductSDto>(); |                 GetProductsResponseDto dto = new GetProductsResponseDto(); | ||||||
|                 if (Search.IsNullOrEmpty()) |                 if (Search.IsNullOrEmpty()) | ||||||
|                 { |                 { | ||||||
|                     dto = await _restWrapper.CrudDtoApiRest<Product, ProductSDto, Guid>(Address.ProductController) |                     dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage); | ||||||
|                         .ReadAll(CurrentPage); |  | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search); |                     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) |                 if (PageDto.Count % 20 == 0) | ||||||
|                     PageCount = CurrentPage + 2; |                     PageCount = CurrentPage + 2; | ||||||
| 
 | 
 | ||||||
|  | @ -96,7 +96,7 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS | ||||||
| 
 | 
 | ||||||
|     public async Task AddProductClicked() |     public async Task AddProductClicked() | ||||||
|     { |     { | ||||||
|         DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; |         DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, DisableBackdropClick = true }; | ||||||
|         var dialogResult = await _dialogService.ShowAsync<ProductActionDialogBox>("افزودن محصول جدید", maxWidth); |         var dialogResult = await _dialogService.ShowAsync<ProductActionDialogBox>("افزودن محصول جدید", maxWidth); | ||||||
|         var result = await dialogResult.Result; |         var result = await dialogResult.Result; | ||||||
|         if (!result.Canceled && result.Data is bool and true) |         if (!result.Canceled && result.Data is bool and true) | ||||||
|  | @ -105,9 +105,21 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public async Task AddDigikalaProductClicked() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; | ||||||
|  |         var dialogResult = await _dialogService.ShowAsync<DigikalaProductActionDialogBox>("افزودن محصول جدید", maxWidth); | ||||||
|  |         var result = await dialogResult.Result; | ||||||
|  |         if (!result.Canceled && result.Data is bool and true) | ||||||
|  |         { | ||||||
|  |             await InitializeAsync(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public async Task EditProductClicked(ProductSDto product) |     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<ProductActionDialogBox>(); |         var parameters = new DialogParameters<ProductActionDialogBox>(); | ||||||
|         parameters.Add(x => x.Product, product); |         parameters.Add(x => x.Product, product); | ||||||
|         var dialogResult = await _dialogService.ShowAsync<ProductActionDialogBox>($"ویرایش محصول {product.PersianName}", parameters, maxWidth); |         var dialogResult = await _dialogService.ShowAsync<ProductActionDialogBox>($"ویرایش محصول {product.PersianName}", parameters, maxWidth); | ||||||
|  | @ -173,7 +185,7 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS | ||||||
|             PageCount = 1; |             PageCount = 1; | ||||||
|             PageDto.Clear(); |             PageDto.Clear(); | ||||||
|             var dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search); |             var dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search); | ||||||
|             dto.ForEach(d => PageDto.Add(d)); |             dto.Products.ForEach(d => PageDto.Add(d)); | ||||||
|             if (PageDto.Count == 20) |             if (PageDto.Count == 20) | ||||||
|                 PageCount = 2; |                 PageCount = 2; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -28,7 +28,13 @@ | ||||||
|                     <Columns> |                     <Columns> | ||||||
|                         <PropertyColumn Title="نام" Property="arg => arg.Name" /> |                         <PropertyColumn Title="نام" Property="arg => arg.Name" /> | ||||||
|                         <PropertyColumn Title="نام انبار ارسال" Property="arg => arg.WarehouseName" /> |                         <PropertyColumn Title="نام انبار ارسال" Property="arg => arg.WarehouseName" /> | ||||||
|                         <PropertyColumn Title="هرینه ارسال" Property="arg => arg.DeliveryCost" /> | 
 | ||||||
|  |                         <TemplateColumn T="ShippingSDto" Title="هزینه ارسال"> | ||||||
|  |                             <CellTemplate> | ||||||
|  |                                 <p>@context.Item.DeliveryCost.ToString("N0") ریالــ</p> | ||||||
|  |                             </CellTemplate> | ||||||
|  |                         </TemplateColumn> | ||||||
|  | 
 | ||||||
|                         <TemplateColumn T="ShippingSDto" Title="ارسال فوری می باشد"> |                         <TemplateColumn T="ShippingSDto" Title="ارسال فوری می باشد"> | ||||||
|                             <CellTemplate> |                             <CellTemplate> | ||||||
|                                 @if (@context.Item.IsExpressShipping) |                                 @if (@context.Item.IsExpressShipping) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,10 @@ | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Services.RestServices; | ||||||
|  | 
 | ||||||
|  | public interface IOrderRestApi | ||||||
|  | { | ||||||
|  |     [Get("")] | ||||||
|  |     Task<List<OrderSDto>> ReadAll([Query]int page, [Query] long? selectedDate, [Query] OrderStatus? orderStatus, [Query] OrderQueryDateFilter? dateFilter, [Header("Authorization")] string authorization); | ||||||
|  | 
 | ||||||
|  |     [Get("/{id}")] | ||||||
|  |     Task<OrderLDto> ReadOne(Guid id, [Header("Authorization")] string authorization); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Services.RestServices; | ||||||
|  | 
 | ||||||
|  | public interface IPageRestApi | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     [Get("/type/{type}")] | ||||||
|  |     Task<BasePageEntitySDto> ReadByType([Query] string type, [Header("Authorization")] string authorization); | ||||||
|  | 
 | ||||||
|  |     [Get("/{id}")] | ||||||
|  |     Task<BasePageEntitySDto> ReadById(Guid id, [Header("Authorization")] string authorization); | ||||||
|  | 
 | ||||||
|  |     [Post("")] | ||||||
|  |     Task CreatePage([Body] PageActionRequestDto request, [Header("Authorization")] string authorization); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Services.RestServices; | ||||||
|  | 
 | ||||||
|  | public interface IPaymentRestApi | ||||||
|  | { | ||||||
|  |     [Get("")] | ||||||
|  |     Task<List<PaymentSDto>> ReadAll([Query] int page, [Header("Authorization")] string authorization); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -1,14 +1,18 @@ | ||||||
| namespace NetinaShop.AdminPanel.PWA.Services.RestServices; | using NetinaShop.Domain.Dtos.ResponseDtos; | ||||||
|  | 
 | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Services.RestServices; | ||||||
| 
 | 
 | ||||||
| public interface IProductRestApi | public interface IProductRestApi | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|     [Get("")] |     [Get("")] | ||||||
|     Task<List<ProductSDto>> ReadAll(); |     Task<GetProductsResponseDto> ReadAll(); | ||||||
|  |     [Get("/{productId}")] | ||||||
|  |     Task<GetProductResponseDto> ReadOne(Guid productId); | ||||||
|     [Get("")] |     [Get("")] | ||||||
|     Task<List<ProductSDto>> ReadAll([Query] int page); |     Task<GetProductsResponseDto> ReadAll([Query] int page); | ||||||
|     [Get("")] |     [Get("")] | ||||||
|     Task<List<ProductSDto>> ReadAll([Query] int page, [Query] string productName); |     Task<GetProductsResponseDto> ReadAll([Query] int page, [Query] string productName); | ||||||
|     [Get("")] |     [Get("")] | ||||||
|     Task<List<ProductSDto>> ReadAll([Query] string productName); |     Task<GetProductsResponseDto> ReadAll([Query] string productName); | ||||||
| } | } | ||||||
|  | @ -16,4 +16,8 @@ public interface IRestWrapper | ||||||
|     public IDiscountRestApi DiscountRest { get; } |     public IDiscountRestApi DiscountRest { get; } | ||||||
|     public IBlogCategoryRestApi BlogCategoryRestApi { get; } |     public IBlogCategoryRestApi BlogCategoryRestApi { get; } | ||||||
|     public IRoleRestApi RoleRestApi { get; } |     public IRoleRestApi RoleRestApi { get; } | ||||||
|  |     public IOrderRestApi OrderRestApi { get; } | ||||||
|  |     public IPaymentRestApi PaymentRestApi { get; } | ||||||
|  |     public IPageRestApi PageRestApi { get; } | ||||||
|  |     public IScraperRestApi ScraperRestApi { get; } | ||||||
| } | } | ||||||
|  | @ -0,0 +1,11 @@ | ||||||
|  | using NetinaShop.Domain.Dtos.ScraperDtos.Response; | ||||||
|  | 
 | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Services.RestServices; | ||||||
|  | 
 | ||||||
|  | public interface IScraperRestApi | ||||||
|  | { | ||||||
|  |     [Get("/digi")] | ||||||
|  |     Task<List<ScraperProductDto>> SearchDigiProductsAsync([Query] string productName, [Header("Authorization")]string authorization); | ||||||
|  |     [Post("/digi/{productId}")] | ||||||
|  |     Task<bool> AddDigiProductToShopAsync(string productId, [Query] string productName, [Header("Authorization")] string authorization); | ||||||
|  | } | ||||||
|  | @ -27,5 +27,9 @@ public class RestWrapper : IRestWrapper | ||||||
|     public IBlogRestApi BlogRestApi => RestService.For<IBlogRestApi>(Address.BlogController, setting); |     public IBlogRestApi BlogRestApi => RestService.For<IBlogRestApi>(Address.BlogController, setting); | ||||||
|     public IDiscountRestApi DiscountRest => RestService.For<IDiscountRestApi>(Address.DiscountController, setting); |     public IDiscountRestApi DiscountRest => RestService.For<IDiscountRestApi>(Address.DiscountController, setting); | ||||||
|     public IBlogCategoryRestApi BlogCategoryRestApi => RestService.For<IBlogCategoryRestApi>(Address.BlogCategoryController, setting); |     public IBlogCategoryRestApi BlogCategoryRestApi => RestService.For<IBlogCategoryRestApi>(Address.BlogCategoryController, setting); | ||||||
|     public IRoleRestApi RoleRestApi => RestService.For<IRoleRestApi>(Address.RoleController); |     public IRoleRestApi RoleRestApi => RestService.For<IRoleRestApi>(Address.RoleController, setting); | ||||||
|  |     public IOrderRestApi OrderRestApi => RestService.For<IOrderRestApi>(Address.OrderController, setting); | ||||||
|  |     public IPaymentRestApi PaymentRestApi => RestService.For<IPaymentRestApi>(Address.PaymentController, setting); | ||||||
|  |     public IPageRestApi PageRestApi => RestService.For<IPageRestApi>(Address.PageController, setting); | ||||||
|  |     public IScraperRestApi ScraperRestApi => RestService.For<IScraperRestApi>(Address.ScraperController, setting); | ||||||
| } | } | ||||||
|  | @ -0,0 +1,37 @@ | ||||||
|  | namespace NetinaShop.AdminPanel.PWA.Utilities.Models; | ||||||
|  |     public class CustomEventHelper | ||||||
|  |     { | ||||||
|  |         private readonly Func<EventArgs, Task> _callback; | ||||||
|  | 
 | ||||||
|  |         public CustomEventHelper(Func<EventArgs, Task> callback) | ||||||
|  |         { | ||||||
|  |             _callback = callback; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [JSInvokable] | ||||||
|  |         public Task OnCustomEvent(EventArgs args) => _callback(args); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public class CustomEventInterop : IDisposable | ||||||
|  |     { | ||||||
|  |         private readonly IJSRuntime _jsRuntime; | ||||||
|  |         private DotNetObjectReference<CustomEventHelper> Reference; | ||||||
|  | 
 | ||||||
|  |         public CustomEventInterop(IJSRuntime jsRuntime) | ||||||
|  |         { | ||||||
|  |             _jsRuntime = jsRuntime; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public ValueTask<string> SetupCustomEventCallback(Func<EventArgs, Task> callback) | ||||||
|  |         { | ||||||
|  |             Reference = DotNetObjectReference.Create(new CustomEventHelper(callback)); | ||||||
|  |             // addCustomEventListener will be a js function we create later | ||||||
|  |             return _jsRuntime.InvokeAsync<string>("addCustomEventListener", Reference); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void Dispose() | ||||||
|  |         { | ||||||
|  |             Reference?.Dispose(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | @ -1084,6 +1084,10 @@ input:checked + .toggle-bg { | ||||||
|   margin-top: 2.5rem; |   margin-top: 2.5rem; | ||||||
|   margin-bottom: 2.5rem; |   margin-bottom: 2.5rem; | ||||||
| } | } | ||||||
|  | .my-2 { | ||||||
|  |   margin-top: 0.5rem; | ||||||
|  |   margin-bottom: 0.5rem; | ||||||
|  | } | ||||||
| .my-4 { | .my-4 { | ||||||
|   margin-top: 1rem; |   margin-top: 1rem; | ||||||
|   margin-bottom: 1rem; |   margin-bottom: 1rem; | ||||||
|  | @ -1128,6 +1132,9 @@ input:checked + .toggle-bg { | ||||||
| .mb-5 { | .mb-5 { | ||||||
|   margin-bottom: 1.25rem; |   margin-bottom: 1.25rem; | ||||||
| } | } | ||||||
|  | .mb-8 { | ||||||
|  |   margin-bottom: 2rem; | ||||||
|  | } | ||||||
| .mr-1 { | .mr-1 { | ||||||
|   margin-right: 0.25rem; |   margin-right: 0.25rem; | ||||||
| } | } | ||||||
|  | @ -1158,6 +1165,9 @@ input:checked + .toggle-bg { | ||||||
| .mt-6 { | .mt-6 { | ||||||
|   margin-top: 1.5rem; |   margin-top: 1.5rem; | ||||||
| } | } | ||||||
|  | .mt-8 { | ||||||
|  |   margin-top: 2rem; | ||||||
|  | } | ||||||
| .line-clamp-1 { | .line-clamp-1 { | ||||||
|   overflow: hidden; |   overflow: hidden; | ||||||
|   display: -webkit-box; |   display: -webkit-box; | ||||||
|  | @ -1224,6 +1234,9 @@ input:checked + .toggle-bg { | ||||||
| .h-96 { | .h-96 { | ||||||
|   height: 24rem; |   height: 24rem; | ||||||
| } | } | ||||||
|  | .h-\[35rem\] { | ||||||
|  |   height: 35rem; | ||||||
|  | } | ||||||
| .h-fit { | .h-fit { | ||||||
|   height: -moz-fit-content; |   height: -moz-fit-content; | ||||||
|   height: fit-content; |   height: fit-content; | ||||||
|  | @ -1237,6 +1250,9 @@ input:checked + .toggle-bg { | ||||||
| .max-h-\[30rem\] { | .max-h-\[30rem\] { | ||||||
|   max-height: 30rem; |   max-height: 30rem; | ||||||
| } | } | ||||||
|  | .max-h-\[40rem\] { | ||||||
|  |   max-height: 40rem; | ||||||
|  | } | ||||||
| .min-h-\[28rem\] { | .min-h-\[28rem\] { | ||||||
|   min-height: 28rem; |   min-height: 28rem; | ||||||
| } | } | ||||||
|  | @ -1429,6 +1445,9 @@ input:checked + .toggle-bg { | ||||||
| .border-0 { | .border-0 { | ||||||
|   border-width: 0px; |   border-width: 0px; | ||||||
| } | } | ||||||
|  | .border-2 { | ||||||
|  |   border-width: 2px; | ||||||
|  | } | ||||||
| .border-4 { | .border-4 { | ||||||
|   border-width: 4px; |   border-width: 4px; | ||||||
| } | } | ||||||
|  | @ -1441,6 +1460,9 @@ input:checked + .toggle-bg { | ||||||
| .border-solid { | .border-solid { | ||||||
|   border-style: solid; |   border-style: solid; | ||||||
| } | } | ||||||
|  | .border-dashed { | ||||||
|  |   border-style: dashed; | ||||||
|  | } | ||||||
| .border-blue-500 { | .border-blue-500 { | ||||||
|   --tw-border-opacity: 1; |   --tw-border-opacity: 1; | ||||||
|   border-color: rgb(63 131 248 / var(--tw-border-opacity)); |   border-color: rgb(63 131 248 / var(--tw-border-opacity)); | ||||||
|  | @ -1469,6 +1491,10 @@ input:checked + .toggle-bg { | ||||||
|   --tw-border-opacity: 1; |   --tw-border-opacity: 1; | ||||||
|   border-color: rgb(104 117 245 / var(--tw-border-opacity)); |   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\] { | .bg-\[\#000000\] { | ||||||
|   --tw-bg-opacity: 1; |   --tw-bg-opacity: 1; | ||||||
|   background-color: rgb(0 0 0 / var(--tw-bg-opacity)); |   background-color: rgb(0 0 0 / var(--tw-bg-opacity)); | ||||||
|  | @ -1556,6 +1582,10 @@ input:checked + .toggle-bg { | ||||||
|   padding-left: 0.5rem; |   padding-left: 0.5rem; | ||||||
|   padding-right: 0.5rem; |   padding-right: 0.5rem; | ||||||
| } | } | ||||||
|  | .px-3 { | ||||||
|  |   padding-left: 0.75rem; | ||||||
|  |   padding-right: 0.75rem; | ||||||
|  | } | ||||||
| .px-4 { | .px-4 { | ||||||
|   padding-left: 1rem; |   padding-left: 1rem; | ||||||
|   padding-right: 1rem; |   padding-right: 1rem; | ||||||
|  | @ -1572,6 +1602,10 @@ input:checked + .toggle-bg { | ||||||
|   padding-top: 0.125rem; |   padding-top: 0.125rem; | ||||||
|   padding-bottom: 0.125rem; |   padding-bottom: 0.125rem; | ||||||
| } | } | ||||||
|  | .py-1 { | ||||||
|  |   padding-top: 0.25rem; | ||||||
|  |   padding-bottom: 0.25rem; | ||||||
|  | } | ||||||
| .py-2 { | .py-2 { | ||||||
|   padding-top: 0.5rem; |   padding-top: 0.5rem; | ||||||
|   padding-bottom: 0.5rem; |   padding-bottom: 0.5rem; | ||||||
|  | @ -1600,6 +1634,9 @@ input:checked + .toggle-bg { | ||||||
| .text-justify { | .text-justify { | ||||||
|   text-align: justify; |   text-align: justify; | ||||||
| } | } | ||||||
|  | .align-bottom { | ||||||
|  |   vertical-align: bottom; | ||||||
|  | } | ||||||
| .text-5xl { | .text-5xl { | ||||||
|   font-size: 3rem; |   font-size: 3rem; | ||||||
| } | } | ||||||
|  | @ -1673,6 +1710,10 @@ input:checked + .toggle-bg { | ||||||
|   --tw-text-opacity: 1; |   --tw-text-opacity: 1; | ||||||
|   color: rgb(225 29 72 / var(--tw-text-opacity)); |   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 { | .text-white { | ||||||
|   --tw-text-opacity: 1; |   --tw-text-opacity: 1; | ||||||
|   color: rgb(255 255 255 / var(--tw-text-opacity)); |   color: rgb(255 255 255 / var(--tw-text-opacity)); | ||||||
|  |  | ||||||
|  | @ -1165,6 +1165,11 @@ input:checked + .toggle-bg { | ||||||
|   margin-bottom: 2.5rem; |   margin-bottom: 2.5rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .my-2 { | ||||||
|  |   margin-top: 0.5rem; | ||||||
|  |   margin-bottom: 0.5rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .my-4 { | .my-4 { | ||||||
|   margin-top: 1rem; |   margin-top: 1rem; | ||||||
|   margin-bottom: 1rem; |   margin-bottom: 1rem; | ||||||
|  | @ -1223,6 +1228,10 @@ input:checked + .toggle-bg { | ||||||
|   margin-bottom: 1.25rem; |   margin-bottom: 1.25rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .mb-8 { | ||||||
|  |   margin-bottom: 2rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .mr-1 { | .mr-1 { | ||||||
|   margin-right: 0.25rem; |   margin-right: 0.25rem; | ||||||
| } | } | ||||||
|  | @ -1263,6 +1272,10 @@ input:checked + .toggle-bg { | ||||||
|   margin-top: 1.5rem; |   margin-top: 1.5rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .mt-8 { | ||||||
|  |   margin-top: 2rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .line-clamp-1 { | .line-clamp-1 { | ||||||
|   overflow: hidden; |   overflow: hidden; | ||||||
|   display: -webkit-box; |   display: -webkit-box; | ||||||
|  | @ -1350,6 +1363,10 @@ input:checked + .toggle-bg { | ||||||
|   height: 24rem; |   height: 24rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .h-\[35rem\] { | ||||||
|  |   height: 35rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .h-fit { | .h-fit { | ||||||
|   height: -moz-fit-content; |   height: -moz-fit-content; | ||||||
|   height: fit-content; |   height: fit-content; | ||||||
|  | @ -1367,6 +1384,10 @@ input:checked + .toggle-bg { | ||||||
|   max-height: 30rem; |   max-height: 30rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .max-h-\[40rem\] { | ||||||
|  |   max-height: 40rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .min-h-\[28rem\] { | .min-h-\[28rem\] { | ||||||
|   min-height: 28rem; |   min-height: 28rem; | ||||||
| } | } | ||||||
|  | @ -1617,6 +1638,10 @@ input:checked + .toggle-bg { | ||||||
|   border-width: 0px; |   border-width: 0px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .border-2 { | ||||||
|  |   border-width: 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .border-4 { | .border-4 { | ||||||
|   border-width: 4px; |   border-width: 4px; | ||||||
| } | } | ||||||
|  | @ -1633,6 +1658,10 @@ input:checked + .toggle-bg { | ||||||
|   border-style: solid; |   border-style: solid; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .border-dashed { | ||||||
|  |   border-style: dashed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .border-blue-500 { | .border-blue-500 { | ||||||
|   --tw-border-opacity: 1; |   --tw-border-opacity: 1; | ||||||
|   border-color: rgb(63 131 248 / var(--tw-border-opacity)); |   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-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\] { | .bg-\[\#000000\] { | ||||||
|   --tw-bg-opacity: 1; |   --tw-bg-opacity: 1; | ||||||
|   background-color: rgb(0 0 0 / var(--tw-bg-opacity)); |   background-color: rgb(0 0 0 / var(--tw-bg-opacity)); | ||||||
|  | @ -1780,6 +1814,11 @@ input:checked + .toggle-bg { | ||||||
|   padding-right: 0.5rem; |   padding-right: 0.5rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .px-3 { | ||||||
|  |   padding-left: 0.75rem; | ||||||
|  |   padding-right: 0.75rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .px-4 { | .px-4 { | ||||||
|   padding-left: 1rem; |   padding-left: 1rem; | ||||||
|   padding-right: 1rem; |   padding-right: 1rem; | ||||||
|  | @ -1800,6 +1839,11 @@ input:checked + .toggle-bg { | ||||||
|   padding-bottom: 0.125rem; |   padding-bottom: 0.125rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .py-1 { | ||||||
|  |   padding-top: 0.25rem; | ||||||
|  |   padding-bottom: 0.25rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .py-2 { | .py-2 { | ||||||
|   padding-top: 0.5rem; |   padding-top: 0.5rem; | ||||||
|   padding-bottom: 0.5rem; |   padding-bottom: 0.5rem; | ||||||
|  | @ -1836,6 +1880,10 @@ input:checked + .toggle-bg { | ||||||
|   text-align: justify; |   text-align: justify; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .align-bottom { | ||||||
|  |   vertical-align: bottom; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .text-5xl { | .text-5xl { | ||||||
|   font-size: 3rem; |   font-size: 3rem; | ||||||
| } | } | ||||||
|  | @ -1930,6 +1978,11 @@ input:checked + .toggle-bg { | ||||||
|   color: rgb(225 29 72 / var(--tw-text-opacity)); |   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 { | .text-white { | ||||||
|   --tw-text-opacity: 1; |   --tw-text-opacity: 1; | ||||||
|   color: rgb(255 255 255 / var(--tw-text-opacity)); |   color: rgb(255 255 255 / var(--tw-text-opacity)); | ||||||
|  |  | ||||||
|  | @ -5,7 +5,9 @@ self.importScripts('./service-worker-assets.js'); | ||||||
| self.addEventListener('install', event => event.waitUntil(onInstall(event))); | self.addEventListener('install', event => event.waitUntil(onInstall(event))); | ||||||
| self.addEventListener('activate', event => event.waitUntil(onActivate(event))); | self.addEventListener('activate', event => event.waitUntil(onActivate(event))); | ||||||
| self.addEventListener('fetch', event => event.respondWith(onFetch(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 cacheNamePrefix = 'offline-cache-'; | ||||||
| const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; | const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; | ||||||
| const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; | const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue