feat: full BackOffice updates - discount shop, blog, content, UI improvements
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 2m20s

- Blog management pages (posts, categories)
- Content management pages (site pages, sections)
- Contract management pages
- Discount shop improvements (order details, product form, categories)
- Wallet management pages
- Commission withdrawal details/reject dialogs
- Orders hub, sales reports
- System hub, global search, breadcrumb
- Club features page, club hub
- UI/UX improvements across all pages
- AppBreadcrumb, GlobalSearch components
- NavMenu updates and styling
This commit is contained in:
masoodafar-web
2026-02-16 00:56:39 +03:30
parent d84dfe3bc5
commit 49017027d0
159 changed files with 11044 additions and 2893 deletions
@@ -1,4 +1,4 @@
@attribute [Route(RouteConstance.Orders)]
@* Merged into OrdersHub — direct route only for per-user orders *@
@attribute [Route(RouteConstance.UserOrder + "{UserId:long}")]
@using CMSMicroservice.Protobuf.Protos.UserOrder
@@ -11,109 +11,58 @@
<BackOffice.Common.BaseComponents.BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared"
OnSubmitClick="OnFilterSubmit">
<Filters>
<MudNumericField HideSpinButtons="true"
T="long?"
Clearable="true"
Label="شناسه سفارش"
@bind-Value="@_orderIdFilter"
Variant="Variant.Outlined"
Margin="Margin.Dense"/>
<UserAutoComplete Label="جستجوی کاربر"
@bind-SelectedUserId="@_userIdFilter" />
<MudNumericField HideSpinButtons="true"
T="long?"
Clearable="true"
Label="شناسه تراکنش"
@bind-Value="@_transactionIdFilter"
Variant="Variant.Outlined"
Margin="Margin.Dense"/>
<MudNumericField HideSpinButtons="true"
T="long?"
Clearable="true"
Label="قیمت"
@bind-Value="@_request.Filter.Amount"
Variant="Variant.Outlined"
Margin="Margin.Dense"/>
<MudDatePicker T="DateTime?"
Label="از تاریخ پرداخت"
@bind-Date="_paymentDateFrom"
Variant="Variant.Outlined"
Margin="Margin.Dense"/>
<MudSelect T="int?"
Clearable="true"
Label="روش پرداخت"
Variant="Variant.Outlined"
Margin="Margin.Dense"
@bind-Value="_paymentMethodFilter">
<MudSelectItem T="int?" Value="@(0)">درگاه پرداخت</MudSelectItem>
<MudSelectItem T="int?" Value="@(1)">کیف پول</MudSelectItem>
</MudSelect>
<MudSelect T="int?"
Clearable="true"
Label="وضعیت پرداخت"
Variant="Variant.Outlined"
Margin="Margin.Dense"
@bind-Value="_paymentStatusFilter">
<MudSelectItem T="int?" Value="@(0)">پرداخت شده</MudSelectItem>
<MudSelectItem T="int?" Value="@(1)">پرداخت نشده</MudSelectItem>
</MudSelect>
<MudSelect T="int?"
Clearable="true"
Label="وضعیت ارسال"
Variant="Variant.Outlined"
Margin="Margin.Dense"
@bind-Value="_deliveryStatusFilter">
<MudSelectItem T="int?" Value="@(1)">در انتظار ارسال</MudSelectItem>
<MudSelectItem T="int?" Value="@(2)">تحویل پست</MudSelectItem>
<MudSelectItem T="int?" Value="@(3)">تحویل به مشتری</MudSelectItem>
<MudSelectItem T="int?" Value="@(4)">مرجوع شده</MudSelectItem>
</MudSelect>
<MudItem xs="12" sm="6" md="3">
<MudNumericField HideSpinButtons="true" T="long?" Clearable="true" Label="شناسه سفارش"
@bind-Value="@_orderIdFilter" Variant="Variant.Outlined" Margin="Margin.Dense"/>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<UserAutoComplete Label="جستجوی کاربر" @bind-SelectedUserId="@_userIdFilter" />
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudNumericField HideSpinButtons="true" T="long?" Clearable="true" Label="شناسه تراکنش"
@bind-Value="@_transactionIdFilter" Variant="Variant.Outlined" Margin="Margin.Dense"/>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudNumericField HideSpinButtons="true" T="long?" Clearable="true" Label="قیمت"
@bind-Value="@_request.Filter.Amount" Variant="Variant.Outlined" Margin="Margin.Dense"/>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudDatePicker T="DateTime?" Label="از تاریخ پرداخت" @bind-Date="_paymentDateFrom"
Variant="Variant.Outlined" Margin="Margin.Dense"/>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudDatePicker T="DateTime?" Label="تا تاریخ پرداخت" @bind-Date="_paymentDateTo"
Variant="Variant.Outlined" Margin="Margin.Dense"/>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudSelect T="int?" Clearable="true" Label="روش پرداخت" Variant="Variant.Outlined"
Margin="Margin.Dense" @bind-Value="_paymentMethodFilter">
<MudSelectItem T="int?" Value="@(0)">درگاه پرداخت</MudSelectItem>
<MudSelectItem T="int?" Value="@(1)">کیف پول</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudSelect T="int?" Clearable="true" Label="وضعیت پرداخت" Variant="Variant.Outlined"
Margin="Margin.Dense" @bind-Value="_paymentStatusFilter">
<MudSelectItem T="int?" Value="@(0)">پرداخت شده</MudSelectItem>
<MudSelectItem T="int?" Value="@(1)">پرداخت نشده</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudSelect T="int?" Clearable="true" Label="وضعیت ارسال" Variant="Variant.Outlined"
Margin="Margin.Dense" @bind-Value="_deliveryStatusFilter">
<MudSelectItem T="int?" Value="@(1)">در انتظار ارسال</MudSelectItem>
<MudSelectItem T="int?" Value="@(2)">تحویل پست</MudSelectItem>
<MudSelectItem T="int?" Value="@(3)">تحویل به مشتری</MudSelectItem>
<MudSelectItem T="int?" Value="@(4)">مرجوع شده</MudSelectItem>
<MudSelectItem T="int?" Value="@(5)">لغو شده</MudSelectItem>
</MudSelect>
</MudItem>
</Filters>
<Content>
<MudGrid Class="mb-2">
@* <MudItem xs="12" md="4">
<MudCard>
<MudCardContent>
<MudText Typo="Typo.subtitle2">جمع سفارش‌ها در بازه فعلی</MudText>
<MudText Typo="Typo.h5">@_stats.TotalOrders.ToString("N0")</MudText>
<MudText Typo="Typo.caption" Color="Color.Secondary">
مجموع مبلغ: @_stats.TotalAmount.ToString("N0") ریال
</MudText>
</MudCardContent>
</MudCard>
</MudItem>
<MudItem xs="12" md="8">
<MudCard>
<MudCardContent>
<MudText Typo="Typo.subtitle2" Class="mb-2">نمودار تعداد سفارش‌ها بر اساس وضعیت ارسال</MudText>
@if (_statusChartLabels.Length == 0)
{
<MudText Typo="Typo.caption" Color="Color.Secondary">
برای این فیلتر، سفارش فعالی یافت نشد.
</MudText>
}
else
{
<MudChart ChartType="ChartType.Bar"
ChartSeries="@_statusChartSeries"
XAxisLabels="@_statusChartLabels"
Height="200px" />
}
</MudCardContent>
</MudCard>
</MudItem> *@
</MudGrid>
<MudDataGrid T="DataModel"
ServerData="@(new Func<GridState<DataModel>, Task<GridData<DataModel>>>(ServerReload))"
Hover="true" @ref="_gridData" Height="60vh">
Hover="true" @ref="_gridData" Height="calc(100vh - 240px)">
<ColGroup>
<col/>
<col/>
@@ -121,8 +70,15 @@
<col style="width: 58px;"/>
</ColGroup>
<ToolBarContent>
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
<MudText>سفارش‌های کاربر</MudText>
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Style="width:100%">
<MudText>لیست سفارشات</MudText>
<MudButton Variant="Variant.Outlined"
Color="Color.Info"
OnClick="ExportToExcel"
StartIcon="@Icons.Material.Filled.FileDownload"
Size="Size.Small">
خروجی Excel
</MudButton>
</MudStack>
</ToolBarContent>
<Columns>
@@ -138,7 +94,20 @@
@(context.Item.VatPercentage > 0 ? $"{context.Item.VatPercentage:0}٪" : "-")
</CellTemplate>
</PropertyColumn> *@
<PropertyColumn Property="x => x.UserFullName" Title="نام کاربر"/>
<TemplateColumn Title="نام کاربر">
<CellTemplate>
@if (context.Item.UserId > 0)
{
<MudLink Href="@($"/network/user-info/{context.Item.UserId}")" Underline="Underline.Hover" Color="Color.Primary">
@context.Item.UserFullName
</MudLink>
}
else
{
<MudText>@context.Item.UserFullName</MudText>
}
</CellTemplate>
</TemplateColumn>
<PropertyColumn Property="x => x.UserNationalCode" Title="کدملی"/>
<TemplateColumn Title="روش پرداخت">
<CellTemplate>
@@ -168,7 +137,14 @@
HeaderStyle="text-wrap: nowrap;"/>
<TemplateColumn Title="تاریخ پرداخت" CellStyle="text-wrap: nowrap;" HeaderStyle="text-wrap: nowrap;">
<CellTemplate>
@(context.Item.PaymentDate.ToDateTime().MiladiToJalaliWithTime())
@if (context.Item.PaymentDate != null)
{
@(context.Item.PaymentDate.ToDateTime().MiladiToJalaliWithTime())
}
else
{
<MudText>-</MudText>
}
</CellTemplate>
</TemplateColumn>
<TemplateColumn Title="آدرس">
@@ -205,7 +181,7 @@
Size="Size.Small"
ButtonType="ButtonType.Button"
OnClick="@(() => OpenDetails(context.Item))"
Style="cursor:pointer;"/>
/>
</MudTooltip>
<MudTooltip Text="تغییر وضعیت ارسال">
@@ -214,7 +190,7 @@
Color="Color.Primary"
ButtonType="ButtonType.Button"
OnClick="@(() => OpenChangeStatus(context.Item))"
Style="cursor:pointer;"/>
/>
</MudTooltip>
<MudTooltip Text="اعمال تخفیف">
@@ -223,7 +199,7 @@
Color="Color.Secondary"
ButtonType="ButtonType.Button"
OnClick="@(() => OpenApplyDiscount(context.Item))"
Style="cursor:pointer;"/>
/>
</MudTooltip>
<MudTooltip Text="لغو سفارش">
@@ -232,22 +208,25 @@
Color="Color.Error"
ButtonType="ButtonType.Button"
OnClick="@(() => OpenCancelOrder(context.Item))"
Style="cursor:pointer;"/>
/>
</MudTooltip>
<MudTooltip Text="آرشیو">
<MudIconButton Icon="@Icons.Material.Filled.DeleteOutline" Size="Size.Small"
ButtonType="ButtonType.Button" OnClick="@(() => OnDelete(context.Item))"
Style="cursor:pointer;"/>
/>
</MudTooltip>
</MudStack>
</CellTemplate>
</TemplateColumn>
</Columns>
<NoRecordsContent>
<MudAlert Severity="Severity.Info" Dense="true" Variant="Variant.Text" Class="my-4">موردی یافت نشد.</MudAlert>
</NoRecordsContent>
<PagerContent>
<MudDataGridPager T="DataModel" PageSizeOptions=@(new int[] { 30, 60, 90 })
<MudDataGridPager T="DataModel" PageSizeOptions=@(new int[] { 20, 50, 100 })
InfoFormat="سطر {first_item} تا {last_item} از {all_items}"
RowsPerPageString="تعداد سطرهای صفحه"/>
RowsPerPageString="تعداد در صفحه"/>
</PagerContent>
</MudDataGrid>