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