feat(address): enhance address management in checkout and summary components
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 6m48s

- Updated the Checkout and CheckoutSummary components to allow users to add new addresses directly from the interface, improving accessibility and user experience.
- Introduced dialog functionality for adding and editing addresses, streamlining the address management process.
- Removed the calculation of order PV from the OrderDetail component, simplifying the order details view and improving performance.

These changes enhance the usability of the checkout process by making address management more intuitive and efficient.
This commit is contained in:
masoodafar-web
2026-08-25 21:40:38 +03:30
parent aae4b2693d
commit c243b59113
8 changed files with 94 additions and 61 deletions
-1
View File
@@ -101,7 +101,6 @@
| 6.6 | `UserOrderContract.SubmitShopBuyOrder` | `UserOrderContract` | `/checkout-summary` | ثبت سفارش و پرداخت از کیف پول | | 6.6 | `UserOrderContract.SubmitShopBuyOrder` | `UserOrderContract` | `/checkout-summary` | ثبت سفارش و پرداخت از کیف پول |
| 6.7 | `OrderService.GetOrdersAsync` | `UserOrderContract.GetCustomerOrders` | `/orders` | لیست سفارش‌های کاربر | | 6.7 | `OrderService.GetOrdersAsync` | `UserOrderContract.GetCustomerOrders` | `/orders` | لیست سفارش‌های کاربر |
| 6.8 | `OrderService.GetOrderAsync` | `UserOrderContract.GetCustomerOrder` | `/order/{id}`, `/order-tracking/{id}` | جزئیات یک سفارش | | 6.8 | `OrderService.GetOrderAsync` | `UserOrderContract.GetCustomerOrder` | `/order/{id}`, `/order-tracking/{id}` | جزئیات یک سفارش |
| 6.9 | `OrderService.CalculateOrderPVAsync` | `UserOrderContract.CalculateOrderPV` | `/order/{id}` | محاسبه PV سفارش |
| 6.10 | `VATService.GetRateAsync` | `UserOrderContract` (via scope) | Store/Discount صفحات قیمت | نرخ مالیات بر ارزش افزوده (کش روزانه) | | 6.10 | `VATService.GetRateAsync` | `UserOrderContract` (via scope) | Store/Discount صفحات قیمت | نرخ مالیات بر ارزش افزوده (کش روزانه) |
| 6.11 | `WalletService.GetBalancesAsync` | `UserWalletContract` | `/checkout-summary` | بررسی موجودی برای پرداخت سفارش | | 6.11 | `WalletService.GetBalancesAsync` | `UserWalletContract` | `/checkout-summary` | بررسی موجودی برای پرداخت سفارش |
@@ -22,9 +22,11 @@
else if (_addresses.Count == 0) else if (_addresses.Count == 0)
{ {
<MudAlert Severity="Severity.Warning"> <MudAlert Severity="Severity.Warning">
هیچ آدرسی ثبت نشده است. لطفاً از بخش پروفایل آدرس خود را اضافه کنید. هیچ آدرسی ثبت نشده است. می‌توانید همین‌جا آدرس جدید اضافه کنید.
</MudAlert> </MudAlert>
<MudButton Class="mt-2" Variant="Variant.Outlined" Href="/profile/addresses">افزودن آدرس</MudButton> <MudButton Class="mt-2" Variant="Variant.Outlined" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="OpenAddAddressDialog">افزودن آدرس</MudButton>
} }
else else
{ {
@@ -41,13 +43,25 @@
<MudText Typo="Typo.subtitle2">@address.Title</MudText> <MudText Typo="Typo.subtitle2">@address.Title</MudText>
<MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText> <MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText>
</MudStack> </MudStack>
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
@if (address.IsDefault) @if (address.IsDefault)
{ {
<MudChip T="string" Color="Color.Success" Variant="Variant.Outlined">پیش‌فرض</MudChip> <MudChip T="string" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Small">پیش‌فرض</MudChip>
} }
<span @onclick:stopPropagation="true">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Size="Size.Small"
Color="Color.Primary"
aria-label="ویرایش آدرس"
OnClick="@(() => OpenEditAddressDialog(address))" />
</span>
</MudStack>
</MudStack> </MudStack>
</MudPaper> </MudPaper>
} }
<MudButton Class="mt-2" Variant="Variant.Text" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="OpenAddAddressDialog">افزودن آدرس جدید</MudButton>
</MudStack> </MudStack>
} }
</MudPaper> </MudPaper>
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using CMSMicroservice.Protobuf.Protos.UserAddress; using CMSMicroservice.Protobuf.Protos.UserAddress;
using FrontOffice.Main.Pages.Profile.Components;
using FrontOffice.Main.Utilities; using FrontOffice.Main.Utilities;
using MudBlazor; using MudBlazor;
@@ -61,12 +62,14 @@ public partial class Checkout
else else
{ {
_addresses = new(); _addresses = new();
_selectedAddress = null;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error); Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error);
_addresses = new(); _addresses = new();
_selectedAddress = null;
} }
finally finally
{ {
@@ -75,6 +78,30 @@ public partial class Checkout
} }
} }
private async Task OpenAddAddressDialog()
{
var dialog = await DialogService.ShowAsync<AddAddressDialog>("افزودن آدرس جدید");
var result = await dialog.Result;
if (result is { Canceled: false })
{
await AuthService.RefreshTokenAsync();
await LoadAddresses();
}
}
private async Task OpenEditAddressDialog(CustomerAddressModel address)
{
var dialog = await DialogService.ShowAsync<EditAddressDialog>("ویرایش آدرس", new DialogParameters<EditAddressDialog>
{
{ x => x.Model, address }
});
var result = await dialog.Result;
if (result is { Canceled: false })
{
await LoadAddresses();
}
}
private async Task PlaceOrder() private async Task PlaceOrder()
{ {
if (!CanPlaceOrder || _selectedAddress is null) if (!CanPlaceOrder || _selectedAddress is null)
@@ -21,9 +21,11 @@
else if (_addresses.Count == 0) else if (_addresses.Count == 0)
{ {
<MudAlert Severity="Severity.Warning"> <MudAlert Severity="Severity.Warning">
هیچ آدرسی ثبت نشده است. لطفاً از بخش پروفایل آدرس خود را اضافه کنید. هیچ آدرسی ثبت نشده است. می‌توانید همین‌جا آدرس جدید اضافه کنید.
</MudAlert> </MudAlert>
<MudButton Class="mt-2" Variant="Variant.Outlined" Href="/profile/addresses">افزودن آدرس</MudButton> <MudButton Class="mt-2" Variant="Variant.Outlined" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="OpenAddAddressDialog">افزودن آدرس</MudButton>
} }
else else
{ {
@@ -40,13 +42,25 @@
<MudText Typo="Typo.subtitle2">@address.Title</MudText> <MudText Typo="Typo.subtitle2">@address.Title</MudText>
<MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText> <MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText>
</MudStack> </MudStack>
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
@if (address.IsDefault) @if (address.IsDefault)
{ {
<MudChip T="string" Color="Color.Success" Variant="Variant.Outlined">پیش‌فرض</MudChip> <MudChip T="string" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Small">پیش‌فرض</MudChip>
} }
<span @onclick:stopPropagation="true">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Size="Size.Small"
Color="Color.Primary"
aria-label="ویرایش آدرس"
OnClick="@(() => OpenEditAddressDialog(address))" />
</span>
</MudStack>
</MudStack> </MudStack>
</MudPaper> </MudPaper>
} }
<MudButton Class="mt-2" Variant="Variant.Text" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="OpenAddAddressDialog">افزودن آدرس جدید</MudButton>
</MudStack> </MudStack>
} }
</MudPaper> </MudPaper>
@@ -1,5 +1,6 @@
using CMSMicroservice.Protobuf.Protos.UserAddress; using CMSMicroservice.Protobuf.Protos.UserAddress;
using CMSMicroservice.Protobuf.Protos.UserOrder; using CMSMicroservice.Protobuf.Protos.UserOrder;
using FrontOffice.Main.Pages.Profile.Components;
using FrontOffice.Main.Shared; using FrontOffice.Main.Shared;
using FrontOffice.Main.Utilities; using FrontOffice.Main.Utilities;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -72,12 +73,14 @@ public partial class CheckoutSummary : ComponentBase
else else
{ {
_addresses = new(); _addresses = new();
_selectedAddress = null;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error); Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error);
_addresses = new(); _addresses = new();
_selectedAddress = null;
} }
finally finally
{ {
@@ -86,6 +89,30 @@ public partial class CheckoutSummary : ComponentBase
} }
} }
private async Task OpenAddAddressDialog()
{
var dialog = await DialogService.ShowAsync<AddAddressDialog>("افزودن آدرس جدید");
var result = await dialog.Result;
if (result is { Canceled: false })
{
await AuthService.RefreshTokenAsync();
await LoadAddresses();
}
}
private async Task OpenEditAddressDialog(CustomerAddressModel address)
{
var dialog = await DialogService.ShowAsync<EditAddressDialog>("ویرایش آدرس", new DialogParameters<EditAddressDialog>
{
{ x => x.Model, address }
});
var result = await dialog.Result;
if (result is { Canceled: false })
{
await LoadAddresses();
}
}
private async Task PlaceOrder() private async Task PlaceOrder()
{ {
if (!CanPlaceOrder || _selectedAddress is null) if (!CanPlaceOrder || _selectedAddress is null)
@@ -112,30 +112,6 @@ else
</MudStack> </MudStack>
} }
</MudStack> </MudStack>
@* نمایش PV سفارش *@
@if (_pvData != null && _pvData.TotalPv > 0)
{
<MudDivider Class="my-2" />
<MudStack Spacing="1" Class="pa-2" Style="background-color: var(--mud-palette-background-grey); border-radius: 8px;">
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIcon Icon="@Icons.Material.Filled.TrendingUp" Color="Color.Info" Size="Size.Small" />
<MudText Typo="Typo.subtitle2" Color="Color.Info">امتیاز فروش (PV)</MudText>
</MudStack>
@foreach (var product in _pvData.Products)
{
<MudStack Row="true" Justify="Justify.SpaceBetween">
<MudText Typo="Typo.caption" Class="mud-text-secondary">@product.ProductTitle × @product.Quantity</MudText>
<MudText Typo="Typo.caption">@string.Format("{0:N0}", product.TotalPv) PV</MudText>
</MudStack>
}
<MudDivider Class="my-1" />
<MudStack Row="true" Justify="Justify.SpaceBetween">
<MudText Typo="Typo.body2" Class="fw-bold">جمع PV:</MudText>
<MudText Typo="Typo.body2" Color="Color.Info" Class="fw-bold">@string.Format("{0:N0}", _pvData.TotalPv) PV</MudText>
</MudStack>
</MudStack>
}
</MudStack> </MudStack>
</MudPaper> </MudPaper>
</MudContainer> </MudContainer>
@@ -12,17 +12,12 @@ public partial class OrderDetail : ComponentBase
[Parameter] public long id { get; set; } [Parameter] public long id { get; set; }
private GetUserOrderResponse? _order; private GetUserOrderResponse? _order;
private CalculateOrderPVResponse? _pvData;
private bool _loading; private bool _loading;
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
_loading = true; _loading = true;
_order = await OrderService.GetOrderAsync(id); _order = await OrderService.GetOrderAsync(id);
if (_order != null)
{
_pvData = await OrderService.CalculateOrderPVAsync(id);
}
_loading = false; _loading = false;
} }
@@ -52,4 +47,3 @@ public partial class OrderDetail : ComponentBase
private static string GetProductImageUrl(string? imageUrl) private static string GetProductImageUrl(string? imageUrl)
=> string.IsNullOrWhiteSpace(imageUrl) ? "/images/product-placeholder.svg" : imageUrl.TrimStart('/'); => string.IsNullOrWhiteSpace(imageUrl) ? "/images/product-placeholder.svg" : imageUrl.TrimStart('/');
} }
@@ -97,22 +97,4 @@ public class OrderService
return 0.10; return 0.10;
} }
} }
/// <summary>
/// محاسبه PV سفارش
/// </summary>
public async Task<CalculateOrderPVResponse?> CalculateOrderPVAsync(long orderId)
{
try
{
return await _userOrderContractClient.CalculateOrderPVAsync(new CalculateOrderPVRequest
{
OrderId = orderId
});
}
catch
{
return null;
}
}
} }