Compare commits

...

2 Commits

11 changed files with 354 additions and 71 deletions

View File

@ -106,6 +106,59 @@
<MudGrid> <MudGrid>
<MudItem xs="12"> <MudItem xs="12">
<MudText Typo="Typo.h6">اطلاعات متا تگ</MudText>
<MudText Typo="Typo.caption">می توانید متا تگ های سئو برای صفحه مورد نظر را وارد کنید</MudText>
<MudGrid>
<MudItem lg="5" md="6">
<MudTextField @bind-Value="@ViewModel.MetaTagType" T="string" Label="نوع" Variant="Variant.Outlined"></MudTextField>
</MudItem>
<MudItem lg="5" md="6">
<MudTextField @bind-Value="@ViewModel.MetaTagValue" T="string" Label="مقدار" Variant="Variant.Outlined"></MudTextField>
</MudItem>
<MudItem lg="2" md="12">
<MudButton Variant="Variant.Filled"
Size="Size.Large"
Color="Color.Info"
class="mt-2 w-full py-3"
OnClick="ViewModel.AddMetaTag"
StartIcon="@Icons.Material.Outlined.Add">افزودن</MudButton>
</MudItem>
<MudItem sm="12">
<MudDataGrid Items="@ViewModel.MetaTags"
T="MetaTagSDto"
Elevation="0"
Outlined="true"
Bordered="true"
Striped="true"
Filterable="false"
SortMode="@SortMode.None"
Groupable="false">
<Columns>
<PropertyColumn T="MetaTagSDto" TProperty="string" Property="x => x.Type" Title="نوع" />
<PropertyColumn T="MetaTagSDto" TProperty="string" Property="x => x.Value" Title="مقدار" />
<TemplateColumn T="MetaTagSDto" CellClass="d-flex justify-end">
<CellTemplate>
<MudStack Row>
<MudButton DisableElevation="true"
Size="@Size.Small"
Variant="@Variant.Filled"
OnClick="()=>ViewModel.MetaTags.Remove(context.Item)"
Color="@Color.Error"
StartIcon="@Icons.Material.Outlined.Delete">حذف</MudButton>
</MudStack>
</CellTemplate>
</TemplateColumn>
</Columns>
</MudDataGrid>
</MudItem>
</MudGrid>
<MudText Typo="Typo.h6">سوالات متداول</MudText> <MudText Typo="Typo.h6">سوالات متداول</MudText>
<MudText Typo="Typo.caption">می توانید سوالات متداول شهر موردنظر را وارد کنید</MudText> <MudText Typo="Typo.caption">می توانید سوالات متداول شهر موردنظر را وارد کنید</MudText>

View File

@ -1,4 +1,7 @@
namespace Netina.AdminPanel.PWA.Dialogs; using Netina.Common.Models.Mapper;
using Netina.Domain.Entities.Seo;
namespace Netina.AdminPanel.PWA.Dialogs;
public class ProductCategoryActionDialogBoxViewModel:BaseViewModel public class ProductCategoryActionDialogBoxViewModel:BaseViewModel
{ {
@ -32,7 +35,8 @@ public class ProductCategoryActionDialogBoxViewModel:BaseViewModel
public string Description = string.Empty; public string Description = string.Empty;
public bool IsMain; public bool IsMain;
public bool IsEditing = false; public bool IsEditing = false;
public readonly ObservableCollection<StorageFileSDto> Files = new ObservableCollection<StorageFileSDto>(); public readonly ObservableCollection<StorageFileSDto> Files = new ();
public readonly ObservableCollection<MetaTagSDto> MetaTags = new();
private ProductCategorySDto? _category = null; private ProductCategorySDto? _category = null;
[Parameter] [Parameter]
@ -59,6 +63,7 @@ public class ProductCategoryActionDialogBoxViewModel:BaseViewModel
var response = await _restWrapper.CrudDtoApiRest<ProductCategory,ProductCategoryLDto,Guid>(Address.ProductCategoryController).ReadOne(Category.Id); var response = await _restWrapper.CrudDtoApiRest<ProductCategory,ProductCategoryLDto,Guid>(Address.ProductCategoryController).ReadOne(Category.Id);
var categoryLDto = response; var categoryLDto = response;
categoryLDto.Files.ForEach(f => Files.Add(f)); categoryLDto.Files.ForEach(f => Files.Add(f));
categoryLDto.MetaTags.ForEach(m=> MetaTags.Add(m));
SelectedCategory = new ProductCategorySDto { Id = categoryLDto.ParentId, Name = categoryLDto.ParentName }; SelectedCategory = new ProductCategorySDto { Id = categoryLDto.ParentId, Name = categoryLDto.ParentName };
Name = categoryLDto.Name; Name = categoryLDto.Name;
Description = categoryLDto.Description; Description = categoryLDto.Description;
@ -100,7 +105,7 @@ public class ProductCategoryActionDialogBoxViewModel:BaseViewModel
SelectedCategory?.Id ?? default, SelectedCategory?.Id ?? default,
Files.ToList(), Files.ToList(),
Faqs, Faqs,
new Dictionary<string, string>()); MetaTags.ToDictionary(x => x.Type, x => x.Value));
await _restWrapper.CrudApiRest<ProductCategory, Guid>(Address.ProductCategoryController).Create<CreateProductCategoryCommand>(request, token); await _restWrapper.CrudApiRest<ProductCategory, Guid>(Address.ProductCategoryController).Create<CreateProductCategoryCommand>(request, token);
_mudDialog.Close(DialogResult.Ok(true)); _mudDialog.Close(DialogResult.Ok(true));
} }
@ -140,7 +145,7 @@ public class ProductCategoryActionDialogBoxViewModel:BaseViewModel
SelectedCategory?.Id ?? default, SelectedCategory?.Id ?? default,
Files.ToList(), Files.ToList(),
Faqs, Faqs,
new Dictionary<string, string>()); MetaTags.ToDictionary(x => x.Type, x => x.Value));
await _restWrapper.CrudApiRest<ProductCategory, Guid>(Address.ProductCategoryController).Update<UpdateProductCategoryCommand>(request, token); await _restWrapper.CrudApiRest<ProductCategory, Guid>(Address.ProductCategoryController).Update<UpdateProductCategoryCommand>(request, token);
_mudDialog.Close(DialogResult.Ok(true)); _mudDialog.Close(DialogResult.Ok(true));
} }
@ -162,6 +167,25 @@ public class ProductCategoryActionDialogBoxViewModel:BaseViewModel
} }
} }
public string MetaTagType { get; set; } = string.Empty;
public string MetaTagValue { get; set; } = string.Empty;
public void AddMetaTag()
{
try
{
if (MetaTagType.IsNullOrEmpty())
throw new Exception("لطفا نوع متا مورد نظر را وارد کنید");
if (MetaTagValue.IsNullOrEmpty())
throw new Exception("لطفا مقدار متا مورد نظر را وارد کنید");
MetaTags.Add(new MetaTagSDto() { Type = MetaTagType, Value = MetaTagValue });
}
catch (Exception e)
{
_snackbar.Add(e.Message, Severity.Error);
}
}
private List<ProductCategorySDto> _productCategories = new List<ProductCategorySDto>(); private List<ProductCategorySDto> _productCategories = new List<ProductCategorySDto>();
public ProductCategorySDto? SelectedCategory; public ProductCategorySDto? SelectedCategory;
public async Task<IEnumerable<ProductCategorySDto>> SearchCategory(string city) public async Task<IEnumerable<ProductCategorySDto>> SearchCategory(string city)

View File

@ -5,8 +5,8 @@
<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>1.5.15.22</AssemblyVersion> <AssemblyVersion>1.6.18.28</AssemblyVersion>
<FileVersion>1.5.15.22</FileVersion> <FileVersion>1.6.18.28</FileVersion>
<AssemblyName>$(MSBuildProjectName)</AssemblyName> <AssemblyName>$(MSBuildProjectName)</AssemblyName>
</PropertyGroup> </PropertyGroup>

View File

@ -2,43 +2,36 @@
namespace Netina.AdminPanel.PWA.Pages; namespace Netina.AdminPanel.PWA.Pages;
public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>> public class BrandsPageViewModel(
NavigationManager navigationManager,
ISnackbar snackbar,
IUserUtility userUtility,
IRestWrapper restWrapper,
IDialogService dialogService) : BaseViewModel<List<BrandSDto>>(userUtility)
{ {
private readonly NavigationManager _navigationManager; private readonly NavigationManager _navigationManager = navigationManager;
private readonly ISnackbar _snackbar; private readonly IUserUtility _userUtility = userUtility;
private readonly IUserUtility _userUtility;
private readonly IDialogService _dialogService;
private readonly IRestWrapper _restWrapper;
public string Search = string.Empty; public string Search = string.Empty;
public int CurrentPage = 0; public int CurrentPage = 0;
public int PageCount = 1; public int PageCount = 1;
public BrandsPageViewModel(NavigationManager navigationManager, ISnackbar snackbar, IUserUtility userUtility, IRestWrapper restWrapper, IDialogService dialogService) : base(userUtility)
{
_navigationManager = navigationManager;
_snackbar = snackbar;
_userUtility = userUtility;
_restWrapper = restWrapper;
_dialogService = dialogService;
}
public override async Task InitializeAsync() public override async Task InitializeAsync()
{ {
try try
{ {
IsProcessing = true; IsProcessing = true;
var dto = await _restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController) var dto = await restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController)
.ReadAll(0); .ReadAll(0);
PageDto = dto; PageDto = dto;
} }
catch (ApiException ex) catch (ApiException ex)
{ {
var exe = await ex.GetContentAsAsync<ApiResult>(); var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
} }
catch (Exception e) catch (Exception e)
{ {
_snackbar.Add(e.Message, Severity.Error); snackbar.Add(e.Message, Severity.Error);
} }
finally finally
{ {
@ -51,18 +44,18 @@ public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>>
public async Task AddBrandClicked() public async Task AddBrandClicked()
{ {
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
await _dialogService.ShowAsync<BrandActionDialogBox>("افزودن برند جدید", maxWidth); await dialogService.ShowAsync<BrandActionDialogBox>("افزودن برند جدید", maxWidth);
} }
public async Task EditBrandAsync(BrandSDto brand) public async Task EditBrandAsync(BrandSDto brand)
{ {
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
var parameters = new DialogParameters<BrandActionDialogBox> { { x => x.Brand, brand } }; var parameters = new DialogParameters<BrandActionDialogBox> { { x => x.Brand, brand } };
await _dialogService.ShowAsync<BrandActionDialogBox>($"ویرایش برند {brand.PersianName}", parameters, maxWidth); await dialogService.ShowAsync<BrandActionDialogBox>($"ویرایش برند {brand.PersianName}", parameters, maxWidth);
} }
public async Task DeleteBrandAsync(Guid selectedCategoryId) public async Task DeleteBrandAsync(Guid selectedCategoryId)
{ {
var reference = await _dialogService.ShowQuestionDialog($"آیا از حذف برند اطمینان دارید ?"); var reference = await dialogService.ShowQuestionDialog($"آیا از حذف برند اطمینان دارید ?");
var result = await reference.Result; var result = await reference.Result;
if (!result.Canceled) if (!result.Canceled)
{ {
@ -72,20 +65,20 @@ public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>>
IsProcessing = true; IsProcessing = true;
var token = await _userUtility.GetBearerTokenAsync(); var token = await _userUtility.GetBearerTokenAsync();
await _restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController) await restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController)
.Delete(selectedCategoryId, token); .Delete(selectedCategoryId, token);
_snackbar.Add("حذف برند با موفقیت انجام شد", Severity.Success); snackbar.Add("حذف برند با موفقیت انجام شد", Severity.Success);
await InitializeAsync(); await InitializeAsync();
} }
catch (ApiException ex) catch (ApiException ex)
{ {
var exe = await ex.GetContentAsAsync<ApiResult>(); var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
} }
catch (Exception e) catch (Exception e)
{ {
_snackbar.Add(e.Message, Severity.Error); snackbar.Add(e.Message, Severity.Error);
} }
finally finally
{ {
@ -102,6 +95,7 @@ public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>>
await InitializeAsync(); await InitializeAsync();
Search = search; Search = search;
} }
public async Task SearchAsync() public async Task SearchAsync()
{ {
try try
@ -112,7 +106,7 @@ public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>>
CurrentPage = 0; CurrentPage = 0;
PageCount = 1; PageCount = 1;
PageDto.Clear(); PageDto.Clear();
var dto = await _restWrapper.BrandRestApi.ReadAll(CurrentPage, Search); var dto = await restWrapper.BrandRestApi.ReadAll(CurrentPage, Search);
dto.ForEach(d => PageDto.Add(d)); dto.ForEach(d => PageDto.Add(d));
if (PageDto.Count == 20) if (PageDto.Count == 20)
PageCount = 2; PageCount = 2;
@ -120,11 +114,11 @@ public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>>
catch (ApiException ex) catch (ApiException ex)
{ {
var exe = await ex.GetContentAsAsync<ApiResult>(); var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
} }
catch (Exception e) catch (Exception e)
{ {
_snackbar.Add(e.Message, Severity.Error); snackbar.Add(e.Message, Severity.Error);
} }
finally finally
{ {
@ -146,12 +140,12 @@ public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>>
List<BrandSDto> dto = new List<BrandSDto>(); List<BrandSDto> dto = new List<BrandSDto>();
if (Search.IsNullOrEmpty()) if (Search.IsNullOrEmpty())
{ {
dto = await _restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController) dto = await restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController)
.ReadAll(CurrentPage); .ReadAll(CurrentPage);
} }
else else
{ {
dto = await _restWrapper.BrandRestApi.ReadAll(CurrentPage, Search); dto = await restWrapper.BrandRestApi.ReadAll(CurrentPage, Search);
} }
dto.ForEach(d => PageDto.Add(d)); dto.ForEach(d => PageDto.Add(d));
@ -162,11 +156,11 @@ public class BrandsPageViewModel : BaseViewModel<List<BrandSDto>>
catch (ApiException ex) catch (ApiException ex)
{ {
var exe = await ex.GetContentAsAsync<ApiResult>(); var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
} }
catch (Exception e) catch (Exception e)
{ {
_snackbar.Add(e.Message, Severity.Error); snackbar.Add(e.Message, Severity.Error);
} }
finally finally
{ {

View File

@ -1,42 +1,36 @@
namespace Netina.AdminPanel.PWA.Pages; namespace Netina.AdminPanel.PWA.Pages;
public class CategoriesPageViewModel : BaseViewModel<ObservableCollection<ProductCategorySDto>> public class CategoriesPageViewModel(
NavigationManager navigationManager,
ISnackbar snackbar,
IUserUtility userUtility,
IRestWrapper restWrapper,
IDialogService dialogService)
: BaseViewModel<ObservableCollection<ProductCategorySDto>>(userUtility)
{ {
private readonly NavigationManager _navigationManager; private readonly NavigationManager _navigationManager = navigationManager;
private readonly ISnackbar _snackbar; private readonly IUserUtility _userUtility = userUtility;
private readonly IUserUtility _userUtility;
private readonly IDialogService _dialogService;
private readonly IRestWrapper _restWrapper;
public string Search = string.Empty; public string Search = string.Empty;
public CategoriesPageViewModel(NavigationManager navigationManager, ISnackbar snackbar, IUserUtility userUtility, IRestWrapper restWrapper, IDialogService dialogService) : base(userUtility)
{
_navigationManager = navigationManager;
_snackbar = snackbar;
_userUtility = userUtility;
_restWrapper = restWrapper;
_dialogService = dialogService;
}
public override async Task InitializeAsync() public override async Task InitializeAsync()
{ {
try try
{ {
IsProcessing = true; IsProcessing = true;
PageDto.Clear(); PageDto.Clear();
var dto = await _restWrapper.ProductCategoryRestApi.ReadAll(true); var dto = await restWrapper.ProductCategoryRestApi.ReadAll(true);
dto.ForEach(d => PageDto.Add(d)); dto.ForEach(d => PageDto.Add(d));
} }
catch (ApiException ex) catch (ApiException ex)
{ {
var exe = await ex.GetContentAsAsync<ApiResult>(); var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
} }
catch (Exception e) catch (Exception e)
{ {
_snackbar.Add(e.Message, Severity.Error); snackbar.Add(e.Message, Severity.Error);
} }
finally finally
{ {
@ -50,7 +44,7 @@ public class CategoriesPageViewModel : BaseViewModel<ObservableCollection<Produc
public async Task AddProductCategoryClicked() public async Task AddProductCategoryClicked()
{ {
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
var dialogResult = await _dialogService.ShowAsync<ProductCategoryActionDialogBox>("افزودن دسته جدید", maxWidth); var dialogResult = await dialogService.ShowAsync<ProductCategoryActionDialogBox>("افزودن دسته جدید", 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)
{ {
@ -63,7 +57,7 @@ public class CategoriesPageViewModel : BaseViewModel<ObservableCollection<Produc
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
var parameters = new DialogParameters<ProductCategoryActionDialogBox>(); var parameters = new DialogParameters<ProductCategoryActionDialogBox>();
parameters.Add(x => x.Category, category); parameters.Add(x => x.Category, category);
var dialogResult = await _dialogService.ShowAsync<ProductCategoryActionDialogBox>($"ویرایش دسته {category.Name}", parameters, maxWidth); var dialogResult = await dialogService.ShowAsync<ProductCategoryActionDialogBox>($"ویرایش دسته {category.Name}", parameters, 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)
{ {
@ -73,7 +67,7 @@ public class CategoriesPageViewModel : BaseViewModel<ObservableCollection<Produc
public async Task DeleteProductCategoryAsync(Guid selectedCategoryId) public async Task DeleteProductCategoryAsync(Guid selectedCategoryId)
{ {
var reference = await _dialogService.ShowQuestionDialog($"آیا از حذف دسته بندی اطمینان دارید ?"); var reference = await dialogService.ShowQuestionDialog($"آیا از حذف دسته بندی اطمینان دارید ?");
var result = await reference.Result; var result = await reference.Result;
if (!result.Canceled) if (!result.Canceled)
{ {
@ -83,20 +77,20 @@ public class CategoriesPageViewModel : BaseViewModel<ObservableCollection<Produc
IsProcessing = true; IsProcessing = true;
var token = await _userUtility.GetBearerTokenAsync(); var token = await _userUtility.GetBearerTokenAsync();
await _restWrapper.CrudDtoApiRest<ProductCategory, ProductCategorySDto, Guid>(Address.ProductCategoryController) await restWrapper.CrudDtoApiRest<ProductCategory, ProductCategorySDto, Guid>(Address.ProductCategoryController)
.Delete(selectedCategoryId, token); .Delete(selectedCategoryId, token);
_snackbar.Add("حذف دسته بندی با موفقیت انجام شد", Severity.Success); snackbar.Add("حذف دسته بندی با موفقیت انجام شد", Severity.Success);
await InitializeAsync(); await InitializeAsync();
} }
catch (ApiException ex) catch (ApiException ex)
{ {
var exe = await ex.GetContentAsAsync<ApiResult>(); var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
} }
catch (Exception e) catch (Exception e)
{ {
_snackbar.Add(e.Message, Severity.Error); snackbar.Add(e.Message, Severity.Error);
} }
finally finally
{ {
@ -114,17 +108,17 @@ public class CategoriesPageViewModel : BaseViewModel<ObservableCollection<Produc
throw new AppException("دسته بندی برای جست جو وارد نشده است"); throw new AppException("دسته بندی برای جست جو وارد نشده است");
IsProcessing = true; IsProcessing = true;
PageDto.Clear(); PageDto.Clear();
var dto = await _restWrapper.ProductCategoryRestApi.ReadAll(Search); var dto = await restWrapper.ProductCategoryRestApi.ReadAll(Search);
dto.ForEach(d => PageDto.Add(d)); dto.ForEach(d => PageDto.Add(d));
} }
catch (ApiException ex) catch (ApiException ex)
{ {
var exe = await ex.GetContentAsAsync<ApiResult>(); var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error); snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
} }
catch (Exception e) catch (Exception e)
{ {
_snackbar.Add(e.Message, Severity.Error); snackbar.Add(e.Message, Severity.Error);
} }
finally finally
{ {
@ -173,7 +167,7 @@ public class CategoriesPageViewModel : BaseViewModel<ObservableCollection<Produc
var token = await _userUtility.GetBearerTokenAsync(); var token = await _userUtility.GetBearerTokenAsync();
if (token == null) if (token == null)
return; return;
var response = await _restWrapper.CrudApiRest<ProductCategory, Guid>(Address.ProductCategoryController) var response = await restWrapper.CrudApiRest<ProductCategory, Guid>(Address.ProductCategoryController)
.Create(command, token); .Create(command, token);
category.Id = response; category.Id = response;
}); });

View File

@ -0,0 +1,92 @@
@page "/crm/customers"
@inject IDialogService DialogService
@inject NavigationManager NavigationManager
@inject IRestWrapper RestWrapper
@inject ISnackbar Snackbar
@inject IUserUtility UserUtility
@* <MudStack class="h-full w-full p-8">
<MudGrid>
<MudItem xs="12">
<MudStack Row="true" class="mb-5">
<MudText Typo="Typo.h4">مشتریان شما</MudText>
<MudSpacer />
</MudStack>
<MudPaper>
<MudDataGrid Striped="true"
T="CustomerSDto"
Items="@ViewModel.PageDto"
Filterable="false"
Loading="@ViewModel.IsProcessing"
CurrentPage="@ViewModel.CurrentPage"
RowsPerPage="15"
SortMode="@SortMode.None" Groupable="false">
<ToolBarContent>
<MudTextField T="string" Placeholder="جست جو بر اساس نام" Adornment="Adornment.Start" Immediate="true"
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto"
ValueChanged="@ViewModel.SearchChanged"
Clearable="true"
OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField>
</ToolBarContent>
<Columns>
<PropertyColumn Title="نام برند" Property="arg => arg.PersianName" />
<PropertyColumn Title="نام انگلیسی برند" Property="arg => arg.EnglishName" />
<PropertyColumn Title="توضیحاتــ" Property="arg => arg.Description" />
<TemplateColumn Title="صفحه اختصاصی دارد" T="BrandSDto">
<CellTemplate>
@if (@context.Item.HasSpecialPage)
{
<p>بلی</p>
}
else
{
<p>خیر</p>
}
</CellTemplate>
</TemplateColumn>
<TemplateColumn CellClass="d-flex justify-end">
<CellTemplate>
<MudStack Row="true">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Size="@Size.Small"
Variant="@Variant.Outlined"
Color="@Color.Info"
OnClick="async()=>await ViewModel.EditBrandAsync(context.Item)"></MudIconButton>
<MudIconButton Icon="@Icons.Material.Filled.Delete"
Size="@Size.Small"
Variant="@Variant.Outlined"
OnClick="async() => await ViewModel.DeleteBrandAsync(context.Item.Id)"
Color="@Color.Error"></MudIconButton>
</MudStack>
</CellTemplate>
</TemplateColumn>
</Columns>
<PagerContent>
<MudStack Row="true" class="w-full">
<MudPagination Rectangular="true" Variant="Variant.Filled" Count="@ViewModel.PageCount"
SelectedChanged="@ViewModel.ChangePageAsync" class="mx-auto my-4" />
</MudStack>
</PagerContent>
</MudDataGrid>
</MudPaper>
</MudItem>
</MudGrid>
</MudStack> *@
@code {
public BrandsPageViewModel ViewModel { get; set; }
protected override async Task OnInitializedAsync()
{
ViewModel = new BrandsPageViewModel(NavigationManager, Snackbar, UserUtility, RestWrapper, DialogService);
await ViewModel.InitializeAsync();
await base.OnInitializedAsync();
}
}

View File

@ -0,0 +1,121 @@
using Netina.Domain.Entities.Brands;
namespace Netina.AdminPanel.PWA.Pages;
public class CustomersPageViewModel(
NavigationManager navigationManager,
ISnackbar snackbar,
IUserUtility userUtility,
IRestWrapper restWrapper,
IDialogService dialogService) : BaseViewModel<ObservableCollection<CustomerSDto>> (userUtility)
{
public string Search = string.Empty;
public int CurrentPage = 0;
public int PageCount = 1;
public override async Task InitializeAsync()
{
try
{
IsProcessing = true;
//var dto = await restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController)
// .ReadAll(0);
//PageDto = dto;
}
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 SearchChanged(string search)
{
if (search.IsNullOrEmpty() && !Search.IsNullOrEmpty())
await InitializeAsync();
Search = search;
}
public async Task SearchAsync()
{
try
{
if (Search.IsNullOrEmpty())
throw new AppException("نام برند برای جست جو وارد نشده است");
IsProcessing = true;
CurrentPage = 0;
PageCount = 1;
PageDto.Clear();
//var dto = await restWrapper.BrandRestApi.ReadAll(CurrentPage, Search);
//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;
}
}
public async Task ChangePageAsync(int page)
{
CurrentPage = page - 1;
if (CurrentPage > PageCount - 2)
{
try
{
IsProcessing = true;
List<BrandSDto> dto = new List<BrandSDto>();
if (Search.IsNullOrEmpty())
{
dto = await restWrapper.CrudDtoApiRest<Brand, BrandSDto, Guid>(Address.BrandController)
.ReadAll(CurrentPage);
}
else
{
dto = await restWrapper.BrandRestApi.ReadAll(CurrentPage, Search);
}
//dto.ForEach(d => PageDto.Add(d));
if (PageDto.Count % 20 == 0)
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;
}
}
}
}

View File

@ -31,7 +31,6 @@
<Columns> <Columns>
<PropertyColumn Title="عنوان" Property="arg => arg.Title" /> <PropertyColumn Title="عنوان" Property="arg => arg.Title" />
<PropertyColumn Title="اسلاگ" Property="arg => arg.Slug" /> <PropertyColumn Title="اسلاگ" Property="arg => arg.Slug" />
<PropertyColumn T="BaseFaq" TProperty="int" Title="تعداد سوالات" Property="arg => arg.Faqs.Count" />
<TemplateColumn CellClass="d-flex justify-end"> <TemplateColumn CellClass="d-flex justify-end">
<CellTemplate> <CellTemplate>
<MudStack Row="true"> <MudStack Row="true">

View File

@ -66,7 +66,7 @@ public class FaqManagementPageViewModel(
{ {
DialogOptions maxWidth = new DialogOptions() DialogOptions maxWidth = new DialogOptions()
{ MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
var reference = await dialogService.ShowAsync<FaqActionDialogBox>("افزودن اژانس هواپیمایی جدید", maxWidth); var reference = await dialogService.ShowAsync<FaqActionDialogBox>("افزودن سوالات متداول جدید", maxWidth);
var result = await reference.Result; var result = await reference.Result;
if (result.Data is bool and true) if (result.Data is bool and true)
await InitializeAsync(); await InitializeAsync();

View File

@ -0,0 +1,6 @@
namespace Netina.AdminPanel.PWA.Services.RestServices;
public interface ICustomerRestApi
{
}

View File

@ -11,8 +11,8 @@
"WebSiteUrl": "https://vesmeh.com", "WebSiteUrl": "https://vesmeh.com",
"AdminPanelBaseUrl": "https://admin.vesmeh.com", "AdminPanelBaseUrl": "https://admin.vesmeh.com",
"StorageBaseUrl": "https://storage.vesmeh.com", "StorageBaseUrl": "https://storage.vesmeh.com",
"ApiUrl": "https://api.vesmeh.com/api", //"ApiUrl": "https://api.vesmeh.com/api",
//"ApiUrl": "http://localhost:32770/api", "ApiUrl": "http://localhost:32770/api",
//"WebSiteUrl": "https://bonsaigallery.shop", //"WebSiteUrl": "https://bonsaigallery.shop",
//"AdminPanelBaseUrl": "https://admin.bonsaigallery.shop", //"AdminPanelBaseUrl": "https://admin.bonsaigallery.shop",