feat: enhance WithdrawalRequests page with payout selection and improved submission logic; add sorting options for products
Build and Deploy / build (push) Successful in 1m18s

This commit is contained in:
masoodafar-web
2025-12-27 06:22:41 +03:30
parent 43cdf7c897
commit e3521af071
10 changed files with 228 additions and 57 deletions
+71 -17
View File
@@ -3,37 +3,91 @@
<PageTitle>محصولات</PageTitle>
<MudContainer MaxWidth="MaxWidth.Large" Class="pa-2 pa-md-6 ">
<MudPaper Elevation="1" Class="pa-4 mb-4 rounded-lg">
<MudContainer MaxWidth="MaxWidth.Large" Class="pa-2 pa-md-6">
<MudPaper Elevation="1" Class="pa-3 pa-md-4 mb-4 rounded-lg">
<MudGrid Spacing="2" AlignItems="AlignItems.Center">
<MudItem xs="12" md="8">
@* ردیف اول: جستجو و دکمه‌ها *@
<MudItem xs="12" md="6">
<MudTextField @bind-Value="_query"
Placeholder="جستجو در محصولات..."
AdornmentIcon="@Icons.Material.Filled.Search"
Adornment="Adornment.Start"
Immediate="true"
OnKeyUp="OnQueryChanged"
Class="w-100"/>
Variant="Variant.Outlined"
Margin="Margin.Dense"/>
</MudItem>
<MudItem xs="12" md="4" Class="d-flex justify-end flex-wrap gap-2">
<MudButton Class="w-100-mobile" Variant="Variant.Outlined" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.ViewList" Href="@RouteConstants.Store.Categories">
<MudItem xs="12" md="6" Class="d-flex justify-start justify-md-end gap-2">
<MudButton Size="Size.Small" Variant="Variant.Outlined" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Category" Href="@RouteConstants.Store.Categories">
دسته‌بندی‌ها
</MudButton>
<MudButton Class="w-100-mobile" Variant="Variant.Filled" Color="Color.Primary"
<MudButton Size="Size.Small" Variant="Variant.Filled" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.ShoppingCart" Href="@RouteConstants.Store.Cart">
سبد خرید (@Cart.Count)
سبد خرید
@if (Cart.Count > 0)
{
<MudBadge Content="@Cart.Count" Color="Color.Error" Overlap="true" Class="ms-2"/>
}
</MudButton>
</MudItem>
@* ردیف دوم: فیلترها و مرتب‌سازی *@
<MudItem xs="12">
<MudDivider Class="my-2"/>
</MudItem>
<MudItem xs="6" sm="4" md="3">
<MudSelect T="ProductSortOption" @bind-Value="_sortOption"
@bind-Value:after="OnSortChanged"
Label="مرتب‌سازی"
Variant="Variant.Outlined"
Margin="Margin.Dense"
AnchorOrigin="Origin.BottomCenter"
AdornmentIcon="@Icons.Material.Filled.Sort">
<MudSelectItem Value="ProductSortOption.PriceDesc">
<div class="d-flex align-center gap-2">
<MudIcon Icon="@Icons.Material.Filled.ArrowDownward" Size="Size.Small"/>
گران‌ترین
</div>
</MudSelectItem>
<MudSelectItem Value="ProductSortOption.PriceAsc">
<div class="d-flex align-center gap-2">
<MudIcon Icon="@Icons.Material.Filled.ArrowUpward" Size="Size.Small"/>
ارزان‌ترین
</div>
</MudSelectItem>
<MudSelectItem Value="ProductSortOption.Newest">
<div class="d-flex align-center gap-2">
<MudIcon Icon="@Icons.Material.Filled.NewReleases" Size="Size.Small"/>
جدیدترین
</div>
</MudSelectItem>
<MudSelectItem Value="ProductSortOption.Title">
<div class="d-flex align-center gap-2">
<MudIcon Icon="@Icons.Material.Filled.SortByAlpha" Size="Size.Small"/>
الفبایی
</div>
</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="6" sm="8" md="9" Class="d-flex align-center">
@if (_activeCategoryId.HasValue)
{
<MudChip T="string" Color="Color.Info" Variant="Variant.Filled" Size="Size.Small"
Icon="@Icons.Material.Filled.FilterAlt"
Closeable="true" OnClose="ClearCategoryFilter">
@(_activeCategoryTitle ?? $"دسته‌بندی #{_activeCategoryId}")
</MudChip>
}
else
{
<MudText Typo="Typo.body2" Class="mud-text-secondary">
<MudIcon Icon="@Icons.Material.Filled.Inventory2" Size="Size.Small" Class="me-1"/>
@(_products.Count) محصول
</MudText>
}
</MudItem>
</MudGrid>
@if (_activeCategoryId.HasValue)
{
<MudStack Spacing="1" Class="mt-3">
<MudChip T="string" Color="Color.Info" Variant="Variant.Filled" Closeable="true" OnClose="ClearCategoryFilter">
@(_activeCategoryTitle ?? $"دسته‌بندی #{_activeCategoryId}")
</MudChip>
</MudStack>
}
</MudPaper>
@if (_loading)
@@ -7,6 +7,14 @@ using FrontOffice.Main.Utilities;
namespace FrontOffice.Main.Pages.Store;
public enum ProductSortOption
{
PriceDesc, // گران‌ترین (پیش‌فرض)
PriceAsc, // ارزان‌ترین
Newest, // جدیدترین
Title // الفبایی
}
public partial class Products : ComponentBase, IDisposable
{
[Inject] private ProductService ProductService { get; set; } = default!;
@@ -19,6 +27,8 @@ public partial class Products : ComponentBase, IDisposable
private List<Product> _products = new();
private long? _activeCategoryId;
private string? _activeCategoryTitle;
private ProductSortOption _sortOption = ProductSortOption.PriceDesc; // پیش‌فرض: گران‌ترین
protected override async Task OnInitializedAsync()
{
@@ -43,13 +53,31 @@ public partial class Products : ComponentBase, IDisposable
{
_loading = true;
UpdateCategoryFilterFromUri();
_products = await ProductService.GetProductsAsync(_query, _activeCategoryId);
var sortBy = GetSortByValue();
_products = await ProductService.GetProductsAsync(_query, _activeCategoryId, sortBy);
_activeCategoryTitle = _activeCategoryId is { } categoryId
? (await CategoryService.GetByIdAsync(categoryId))?.Title
: null;
_loading = false;
}
private string GetSortByValue()
{
return _sortOption switch
{
ProductSortOption.PriceDesc => "price desc",
ProductSortOption.PriceAsc => "price asc",
ProductSortOption.Newest => "id desc",
ProductSortOption.Title => "title asc",
_ => "price desc"
};
}
private async Task OnSortChanged()
{
await Load();
}
private async Task OnQueryChanged(KeyboardEventArgs _)
{
await Load();