feat(AddBanner) , feat(AddCatelog) , feat(AddPersonalizationPage)

subProduct
Amir Hossein Khademi 2024-08-06 14:26:39 +03:30
parent d457803c30
commit 77a6cf80a2
4 changed files with 417 additions and 0 deletions

View File

@ -43,6 +43,10 @@
<MudNavLink Href="management/faqs" Icon="@Icons.Material.Filled.ManageAccounts">سوالات متداول</MudNavLink>
</MudNavGroup>
<MudNavGroup Title="شخصی سازی" Expanded="false" Icon="@Icons.Material.Filled.SettingsSystemDaydream">
<MudNavLink Href="personaliztion/main" Icon="@Icons.Material.Filled.SettingsBrightness">کاتالوگ و بنرها</MudNavLink>
</MudNavGroup>
@if (isShop)
{
<MudNavGroup Title="حسابداری" Expanded="false"

View File

@ -0,0 +1,243 @@
@page "/personaliztion/main"
@attribute [Microsoft.AspNetCore.Authorization.Authorize]
@inject IDialogService DialogService
@inject ISnackbar Snackbar
@inject IUserUtility UserUtility
@inject IRestWrapper RestWrapper
@inject NavigationManager NavigationManager
@inject IConfiguration Configuration
@inject IJSRuntime JsRuntime
<MudStack class="h-full w-full p-8">
<MudPaper class="px-5 py-5">
<MudStack Row="true">
<MudStack class="mx-2 mb-5">
<MudText Typo="Typo.h4">اطلاعات بنر ها وکاتالوگ</MudText>
<MudText Typo="Typo.caption">بنر ها و کاتالوگ در صفحه اصلی و دیگر صفحه ها نمایش داده خواهند شد</MudText>
</MudStack>
<MudSpacer />
<BaseButtonUi Size="Size.Large"
OnClickCallback="ViewModel.SubmitSettingAsync"
class="mb-8 mt-2 w-64 rounded-md"
IsProcessing="@ViewModel.IsProcessing"
Icon="@Icons.Material.Outlined.Check"
Content="ثبتـــ اطلاعات" Variant="Variant.Filled" Color="Color.Success" />
</MudStack>
<MudDivider />
<MudStack class="mt-3">
<MudText Typo="Typo.h6">بنر های سایت شما</MudText>
</MudStack>
<MudGrid>
<MudItem xs="12" md="4">
<MudTextField T="string" @bind-Value="@ViewModel.NewBanner.Title" class="my-2" Variant="Variant.Outlined" Label="عنوان بنر"></MudTextField>
<MudTextField T="string" @bind-Value="@ViewModel.NewBanner.Link" class="my-2" Variant="Variant.Outlined" Label="لینک بنر"></MudTextField>
<MudTextField T="string" @bind-Value="@ViewModel.NewBanner.Description" class="my-2" Variant="Variant.Outlined" Label="توضیحات بنر"></MudTextField>
<MudSelect Variant="Variant.Outlined" class="my-2" T="BannerSection" ToStringFunc="type => type.ToDisplay()" Label="محل قرارگیری بنر" @bind-Value="ViewModel.NewBanner.Section">
@foreach (var state in Enum.GetValues(typeof(BannerSection)).Cast<BannerSection>())
{
<MudSelectItem T="BannerSection" Value="@state"></MudSelectItem>
}
</MudSelect>
@if (ViewModel.NewBanner.ImageLocation.IsNullOrEmpty())
{
<MudButton class="mt-3"
Variant="Variant.Outlined"
FullWidth="true"
Color="Color.Info"
OnClick="@ViewModel.SelectFileAsync">انتخاب تصویر بنر</MudButton>
}
else
{
<MudButton class="mt-3"
Variant="Variant.Filled"
FullWidth="true"
Color="Color.Info"
OnClick="@ViewModel.SelectFileAsync">انتخاب تصویر دیگر</MudButton>
}
<MudButton class="mt-3"
Variant="Variant.Outlined"
FullWidth="true"
Color="Color.Info"
OnClick="@ViewModel.AddBanner">افزودن بنر</MudButton>
</MudItem>
<MudItem xs="12" md="8">
<MudDataGrid Items="@ViewModel.PageDto.Banners"
T="BannerItemModel"
Elevation="0"
Outlined="true"
Bordered="true"
Striped="false"
Dense="true"
Filterable="false"
SortMode="@SortMode.None"
Groupable="false">
<Columns>
<PropertyColumn T="BannerItemModel" TProperty="string" Property="x => x.Title" Title="نام فارسی" />
<TemplateColumn T="BannerItemModel" Title="جایگاه بنر" CellClass="d-flex justify-end">
<CellTemplate>
<MudStack Row="true">
<MudText Align="Align.Center">@context.Item.Section.ToDisplay()</MudText>
</MudStack>
</CellTemplate>
</TemplateColumn>
<PropertyColumn T="BannerItemModel" TProperty="string" Property="x => x.Description" Title="نام انگلیسی" />
<TemplateColumn T="BannerItemModel" CellClass="d-flex justify-end">
<CellTemplate>
<MudStack Row="true">
<MudButton DisableElevation="true"
Size="@Size.Small"
Variant="@Variant.Outlined"
OnClick="async()=>await ShowBannerPhoto(context.Item.ImageLocation)"
Color="@Color.Info"
StartIcon="@Icons.Material.Filled.RemoveRedEye">مشاهده تصویر</MudButton>
<MudButton DisableElevation="true"
Size="@Size.Small"
Variant="@Variant.Outlined"
OnClick="async()=>await ShowBannerLink(context.Item.Link)"
Color="@Color.Info"
StartIcon="@Icons.Material.Outlined.AttachFile">مشاهده لینک</MudButton>
<MudButton DisableElevation="true"
Size="@Size.Small"
Variant="@Variant.Outlined"
OnClick="() => ViewModel.PageDto.Banners.Remove(context.Item)"
Color="@Color.Error"
StartIcon="@Icons.Material.Outlined.Delete">حذف</MudButton>
</MudStack>
</CellTemplate>
</TemplateColumn>
</Columns>
</MudDataGrid>
</MudItem>
</MudGrid>
<MudDivider class="mt-5" />
<MudStack class="mb-1 mt-3" Spacing="0">
<MudText Typo="Typo.h6">کاتالوگ سایت شما</MudText>
<MudText Typo="Typo.caption">کاتالوگ به لیست فهرست مانند صفحه اصلی گفته میشود که تورهای مختلف را نمایش میدهد</MudText>
</MudStack>
<MudGrid>
<MudItem xs="12" sm="6" lg="1">
<MudTextField T="int" @bind-Value="@ViewModel.NewCatalogItem.Row" Variant="Variant.Outlined" Label="ردیف"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6" lg="4">
<MudTextField T="string" @bind-Value="@ViewModel.NewCatalogItem.PersianName" Variant="Variant.Outlined" Label="نام فارسی کاتالوگ"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6" lg="4">
<MudTextField T="string" @bind-Value="@ViewModel.NewCatalogItem.EnglishName" Variant="Variant.Outlined" Label="نام انگلیسی"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6" lg="3">
<MudAutocomplete ToStringFunc="dto => dto.PersianName"
T="CatalogItemModel"
@bind-Value="ViewModel.SelectedCatalog"
MaxItems="306"
SearchFunc="ViewModel.SearchCatalog"
Label="کاتالوگ پدر"
Variant="Variant.Outlined">
<ItemTemplate Context="e">
<p>@e.PersianName</p>
</ItemTemplate>
</MudAutocomplete>
</MudItem>
<MudItem xs="12" sm="6" lg="6">
<MudTextField T="string" @bind-Value="@ViewModel.NewCatalogItem.Query" Variant="Variant.Outlined" Label="کوئری"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6" lg="3">
@if (ViewModel.CatalogImage.IsNullOrEmpty())
{
<MudButton class="mt-3 py-3"
Variant="Variant.Outlined"
FullWidth="true"
Color="Color.Info"
OnClick="@ViewModel.SelectCatalogFileAsync">انتخاب تصویر کاتالوگ</MudButton>
}
else
{
<MudButton class="mt-3 py-3"
Variant="Variant.Filled"
FullWidth="true"
Color="Color.Info"
OnClick="@ViewModel.SelectCatalogFileAsync">انتخاب تصویر دیگر</MudButton>
}
</MudItem>
<MudItem xs="12" sm="6" lg="2">
<MudButton Variant="Variant.Outlined"
FullWidth="true"
class="mt-2 py-3"
Color="Color.Info"
OnClick="@ViewModel.AddCatalogItem">+</MudButton>
</MudItem>
</MudGrid>
<MudDataGrid Items="@ViewModel.PageDto.Catalog"
T="CatalogItemModel"
class="mt-2"
Elevation="0"
Outlined="true"
Bordered="false"
Dense="true"
Striped="false"
Filterable="false"
SortMode="@SortMode.None"
Groupable="false">
<Columns>
<PropertyColumn T="CatalogItemModel" TProperty="int" Property="x => x.Row" Title=" " />
<PropertyColumn T="CatalogItemModel" TProperty="string" Property="x => x.PersianName" Title="نام فارسی" />
<PropertyColumn T="CatalogItemModel" TProperty="string" Property="x => x.ParentName" Title="دسته پدر" />
<PropertyColumn T="CatalogItemModel" TProperty="string" Property="x => x.EnglishName" Title="نام انگلیسی" />
<PropertyColumn T="CatalogItemModel" TProperty="string" Property="x => x.Query" Title="کوئری" />
<TemplateColumn T="CatalogItemModel" CellClass="d-flex justify-end">
<CellTemplate>
<MudStack Row>
<MudButton DisableElevation="true"
Size="@Size.Small"
Variant="@Variant.Outlined"
OnClick="() => ViewModel.PageDto.Catalog.Remove(context.Item)"
Color="@Color.Error"
StartIcon="@Icons.Material.Outlined.Delete">حذف</MudButton>
</MudStack>
</CellTemplate>
</TemplateColumn>
</Columns>
</MudDataGrid>
</MudPaper>
</MudStack>
@code
{
public PersonalizationPageViewModel ViewModel { get; set; }
protected override async Task OnInitializedAsync()
{
ViewModel = new PersonalizationPageViewModel(DialogService, RestWrapper, Snackbar, NavigationManager, UserUtility);
await ViewModel.InitializeAsync();
await base.OnInitializedAsync();
}
private async Task ShowBannerPhoto(string photoUrl)
{
var webUrl = Configuration.GetValue<string>("StorageBaseUrl") ?? string.Empty;
var url = $"{webUrl}/{photoUrl}";
await JsRuntime.InvokeVoidAsyncIgnoreErrors("open", url, "_blank");
}
private async Task ShowBannerLink(string url)
{
await JsRuntime.InvokeVoidAsyncIgnoreErrors("open", url, "_blank");
}
}
}

View File

@ -0,0 +1,167 @@
using System.Net.Http.Json;
namespace Netina.AdminPanel.PWA.Pages.Personalization;
public class PersonalizationPageViewModel(IDialogService dialogService, IRestWrapper restWrapper,
ISnackbar snackbar, NavigationManager navigationManager, IUserUtility userUtility)
: BaseViewModel<PersonalizationSetting>(userUtility: userUtility)
{
public override async Task InitializeAsync()
{
try
{
var token = await userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
var personalizationSetting = await restWrapper.SettingRestApi.GetSettingAsync<PersonalizationSetting>(nameof(PersonalizationSetting), token);
personalizationSetting.Catalog = personalizationSetting.Catalog.OrderBy(c => c.Row).ToList();
PageDto = personalizationSetting;
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
if (ex.StatusCode == HttpStatusCode.Unauthorized)
{
await userUtility.LogoutAsync();
navigationManager.NavigateTo("login", true, true);
}
snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
}
catch (Exception e)
{
snackbar.Add(e.Message, Severity.Error);
}
await base.InitializeAsync();
}
public async Task SubmitSettingAsync()
{
try
{
var token = await userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
await restWrapper.SettingRestApi.PostSettingAsync(nameof(PersonalizationSetting), PageDto, token);
snackbar.Add("تنظیمات شخصی سازی با موفقیت تغییر یافت", Severity.Success);
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
if (ex.StatusCode == HttpStatusCode.Unauthorized)
{
await userUtility.LogoutAsync();
navigationManager.NavigateTo("login", true, true);
}
snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
}
catch (Exception e)
{
snackbar.Add(e.Message, Severity.Error);
}
}
public BannerItemModel NewBanner { get; set; } = new();
public CatalogItemModel NewCatalogItem { get; set; } = new();
public void AddBanner()
{
try
{
if (NewBanner.ImageLocation.IsNullOrEmpty())
throw new Exception("تصویر بنر انتخاب نشده است");
if (NewBanner.Title.IsNullOrEmpty())
throw new Exception("عنوان بنر انتخاب نشده است");
PageDto.Banners.Add(NewBanner);
NewBanner = new BannerItemModel();
}
catch (Exception e)
{
snackbar.Add(e.Message, Severity.Error);
}
}
public async Task SelectFileAsync()
{
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, DisableBackdropClick = true };
var dialog = await dialogService.ShowAsync<StorageDialogBox>("انتخاب عکس", maxWidth);
var result = await dialog.Result;
var file = result.Data;
if (file is StorageFileSDto storageFile)
{
NewBanner.ImageLocation = storageFile.FileLocation;
}
}
public CatalogItemModel? SelectedCatalog { get; set; }
public async Task<IEnumerable<CatalogItemModel>> SearchCatalog(string catelogName)
{
try
{
if (catelogName.IsNullOrEmpty())
return PageDto.Catalog;
return PageDto.Catalog.Where(f => f.PersianName.Contains(catelogName));
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
return new List<CatalogItemModel>();
}
catch (Exception e)
{
snackbar.Add(e.Message, Severity.Error);
return new List<CatalogItemModel>();
}
}
public string CatalogImage { get; set; } = string.Empty;
public async Task SelectCatalogFileAsync()
{
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, DisableBackdropClick = true };
var dialog = await dialogService.ShowAsync<StorageDialogBox>("انتخاب عکس", maxWidth);
var result = await dialog.Result;
var file = result.Data;
if (file is StorageFileSDto storageFile)
{
CatalogImage = storageFile.FileLocation;
}
}
public void AddCatalogItem()
{
try
{
if (NewCatalogItem.EnglishName.IsNullOrEmpty())
throw new Exception("نام انگلیسی را وارد کنید");
if (NewCatalogItem.PersianName.IsNullOrEmpty())
throw new Exception("نام فارسی ایتم کاتالوگ را وارد کنید");
if (NewCatalogItem.Query.IsNullOrEmpty())
throw new Exception("کوئری ایتم کاتالوگ را وارد کنید");
if (SelectedCatalog != null)
{
NewCatalogItem.ParentId = SelectedCatalog.Id;
NewCatalogItem.ParentName = SelectedCatalog.PersianName;
}
else
NewCatalogItem.IsMain = true;
if (!CatalogImage.IsNullOrEmpty())
NewCatalogItem.ImageLocation = CatalogImage;
CatalogImage = string.Empty;
NewCatalogItem.Id = Guid.NewGuid();
PageDto.Catalog.Add(NewCatalogItem);
PageDto.Catalog = PageDto.Catalog.OrderBy(c => c.Row).ToList();
NewCatalogItem = new CatalogItemModel();
}
catch (Exception e)
{
snackbar.Add(e.Message, Severity.Error);
}
}
}

View File

@ -1209,6 +1209,9 @@ input:checked + .toggle-bg {
.mt-4 {
margin-top: 1rem;
}
.mt-5 {
margin-top: 1.25rem;
}
.mt-6 {
margin-top: 1.5rem;
}