refactor(checkout): simplify address management and improve package selection logic
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 2m45s
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 2m45s
- Removed the address selection UI and related logic from the Checkout page to streamline the user experience. - Updated the payment validation to only require package selection, enhancing clarity for users. - Adjusted the loading of addresses in related components based on user authentication status, ensuring addresses are only loaded when available. These changes improve the overall usability of the checkout process by focusing on essential selections and reducing unnecessary complexity.
This commit is contained in:
@@ -71,80 +71,6 @@
|
||||
</MudStack>
|
||||
}
|
||||
</MudPaper>
|
||||
|
||||
<!-- Address Selection -->
|
||||
<MudPaper Elevation="2" Class="pa-4 rounded-lg">
|
||||
<MudText Typo="Typo.h5" Class="mb-4">انتخاب آدرس</MudText>
|
||||
|
||||
@if (_isLoadingAddresses)
|
||||
{
|
||||
<MudStack AlignItems="AlignItems.Center" Class="py-4">
|
||||
<MudProgressCircular Color="Color.Primary" Indeterminate="true" Size="Size.Medium" />
|
||||
<MudText Typo="Typo.body2" Class="mud-text-secondary mt-2">بارگذاری آدرسها...</MudText>
|
||||
</MudStack>
|
||||
}
|
||||
else if (_addresses.Any())
|
||||
{
|
||||
<MudStack Spacing="2">
|
||||
@foreach (var address in _addresses)
|
||||
{
|
||||
<MudPaper Outlined="@(_selectedAddress?.Id != address.Id)"
|
||||
Elevation="@(_selectedAddress?.Id == address.Id ? 4 : 0)"
|
||||
Class="pa-3 rounded-xl cursor-pointer"
|
||||
Style="@(_selectedAddress?.Id == address.Id ? "border: 2px solid var(--mud-palette-primary);" : "")"
|
||||
@onclick="() => SetAddressAsDefault(address.Id)">
|
||||
<MudStack Spacing="1">
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
||||
<MudCheckBox @bind-Value="address.IsDefault"
|
||||
Disabled="true"
|
||||
Color="Color.Primary" />
|
||||
<MudText Typo="Typo.subtitle2">@(address.Title)</MudText>
|
||||
@if (address.IsDefault)
|
||||
{
|
||||
<MudChip T="string" Color="Color.Success" Variant="Variant.Filled" Size="Size.Small">پیشفرض</MudChip>
|
||||
}
|
||||
@if (!address.IsDefault)
|
||||
{
|
||||
@if (_isSettingDefaultAddress && _settingDefaultAddressId == address.Id)
|
||||
{
|
||||
<MudProgressCircular Size="Size.Small" Color="Color.Primary" Indeterminate="true" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudButton Variant="Variant.Text"
|
||||
Color="Color.Primary"
|
||||
Size="Size.Small"
|
||||
OnClick="() => SetAddressAsDefault(address.Id)">
|
||||
تنظیم به عنوان پیشفرض
|
||||
</MudButton>
|
||||
}
|
||||
}
|
||||
</MudStack>
|
||||
<MudStack Row="true">
|
||||
<MudText Typo="Typo.body2" Class="mud-text-secondary">@(address.Address)</MudText>
|
||||
<MudSpacer />
|
||||
<MudText Typo="Typo.caption" Class="mud-text-secondary">کد پستی: @(address.PostalCode)</MudText>
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
}
|
||||
</MudStack>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudStack AlignItems="AlignItems.Center" Class="py-4">
|
||||
<MudIcon Icon="@Icons.Material.Filled.LocationOff" Size="Size.Large" Color="Color.Default" />
|
||||
<MudText Typo="Typo.body2" Class="mud-text-secondary mt-2">آدرسی ثبت نشده است.</MudText>
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Primary"
|
||||
StartIcon="@Icons.Material.Filled.Add"
|
||||
OnClick="() => Navigation.NavigateTo(RouteConstants.Profile.Index)"
|
||||
Class="mt-2">
|
||||
افزودن آدرس
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
}
|
||||
</MudPaper>
|
||||
</MudStack>
|
||||
</MudItem>
|
||||
|
||||
@@ -241,7 +167,7 @@
|
||||
@if (!CanProceedToPayment)
|
||||
{
|
||||
<MudText Typo="Typo.caption" Color="Color.Error" Align="Align.Center">
|
||||
لطفاً پکیج و آدرس را انتخاب کنید.
|
||||
لطفاً پکیج را انتخاب کنید.
|
||||
</MudText>
|
||||
}
|
||||
</MudStack>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
using CMSMicroservice.Protobuf.Protos.Package;
|
||||
using CMSMicroservice.Protobuf.Protos.UserAddress;
|
||||
using FrontOffice.Main.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
@@ -13,14 +11,11 @@ public partial class Checkout
|
||||
{
|
||||
[Inject] private PackageService PackageService { get; set; } = default!;
|
||||
[Inject] private PackageContract.PackageContractClient PackageClient { get; set; } = default!;
|
||||
[Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!;
|
||||
[Inject] private IJSRuntime JSRuntime { get; set; } = default!;
|
||||
|
||||
[Parameter] public long? PackageId { get; set; }
|
||||
|
||||
private Pack? _selectedPackage;
|
||||
private List<CustomerAddressModel> _addresses = new();
|
||||
private CustomerAddressModel? _selectedAddress;
|
||||
private bool _isLoadingAddresses;
|
||||
private bool _isProcessingPayment;
|
||||
|
||||
// Discount code
|
||||
@@ -31,16 +26,11 @@ public partial class Checkout
|
||||
private long _discountAmount;
|
||||
private long _finalPrice;
|
||||
|
||||
// Address management
|
||||
private bool _isSettingDefaultAddress;
|
||||
private long? _settingDefaultAddressId;
|
||||
|
||||
private bool CanProceedToPayment => _selectedPackage != null && _selectedAddress != null;
|
||||
private bool CanProceedToPayment => _selectedPackage != null;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadPackageDetails();
|
||||
await LoadAddresses();
|
||||
}
|
||||
|
||||
private async Task LoadPackageDetails()
|
||||
@@ -72,60 +62,6 @@ public partial class Checkout
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadAddresses()
|
||||
{
|
||||
_isLoadingAddresses = true;
|
||||
try
|
||||
{
|
||||
var response = await UserAddressContract.GetCustomerAddressesAsync(request: new());
|
||||
if (response?.Models?.Any() == true)
|
||||
{
|
||||
_addresses = response.Models.ToList();
|
||||
// Select default address if available
|
||||
_selectedAddress = _addresses.FirstOrDefault(a => a.IsDefault) ?? _addresses.First();
|
||||
}
|
||||
else
|
||||
{
|
||||
_addresses = new List<CustomerAddressModel>();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"خطا در بارگذاری آدرسها: {ex.Message}", Severity.Error);
|
||||
_addresses = new List<CustomerAddressModel>();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isLoadingAddresses = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SetAddressAsDefault(long addressId)
|
||||
{
|
||||
if (_isSettingDefaultAddress) return;
|
||||
|
||||
_isSettingDefaultAddress = true;
|
||||
_settingDefaultAddressId = addressId;
|
||||
|
||||
try
|
||||
{
|
||||
await UserAddressContract.SetAddressAsDefaultAsync(new() { Id = addressId });
|
||||
await LoadAddresses(); // Reload addresses to reflect the change
|
||||
Snackbar.Add("آدرس پیشفرض با موفقیت تغییر یافت.", Severity.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"خطا در تغییر آدرس پیشفرض: {ex.Message}", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isSettingDefaultAddress = false;
|
||||
_settingDefaultAddressId = null;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ApplyDiscountCode()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_discountCode))
|
||||
@@ -157,7 +93,7 @@ public partial class Checkout
|
||||
_finalPrice = _selectedPackage!.Price;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
_discountMessage = "خطا در اعمال کد تخفیف.";
|
||||
_discountApplied = false;
|
||||
@@ -175,9 +111,9 @@ public partial class Checkout
|
||||
{
|
||||
if (_isProcessingPayment) return;
|
||||
|
||||
if (!CanProceedToPayment || _selectedPackage == null || _selectedAddress == null)
|
||||
if (!CanProceedToPayment || _selectedPackage == null)
|
||||
{
|
||||
Snackbar.Add("لطفاً پکیج و آدرس را انتخاب کنید.", Severity.Warning);
|
||||
Snackbar.Add("لطفاً پکیج را انتخاب کنید.", Severity.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -219,9 +155,9 @@ public partial class Checkout
|
||||
|
||||
private async Task DayaLoanPayment()
|
||||
{
|
||||
if (_selectedAddress == null)
|
||||
if (_selectedPackage == null)
|
||||
{
|
||||
Snackbar.Add("لطفاً آدرس را انتخاب کنید.", Severity.Warning);
|
||||
Snackbar.Add("لطفاً پکیج را انتخاب کنید.", Severity.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,11 @@ public partial class Checkout
|
||||
}
|
||||
await VAT.LoadAsync();
|
||||
await DiscountCart.EnsureInitializedAsync();
|
||||
var userInfo = await AuthService.GetUserAuthInfo();
|
||||
if (userInfo.HasAddress)
|
||||
await LoadAddresses();
|
||||
else
|
||||
_addresses = new();
|
||||
}
|
||||
|
||||
private async Task LoadAddresses()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using CMSMicroservice.Protobuf.Protos.UserAddress;
|
||||
using FrontOffice.Main.Utilities;
|
||||
using CMSMicroservice.Protobuf.Protos.UserAddress;
|
||||
using FrontOffice.Main.Pages.Profile.Components;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@@ -9,6 +9,7 @@ namespace FrontOffice.Main.Pages.Profile;
|
||||
public partial class Addresses : ComponentBase
|
||||
{
|
||||
[Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!;
|
||||
[Inject] private AuthService AuthService { get; set; } = default!;
|
||||
|
||||
private List<CustomerAddressModel> _addresses = new();
|
||||
private bool _isLoadingAddresses;
|
||||
@@ -42,7 +43,10 @@ public partial class Addresses : ComponentBase
|
||||
var dialog = await DialogService.ShowAsync<AddAddressDialog>("افزودن آدرس جدید");
|
||||
var result = await dialog.Result;
|
||||
if (result is not null && !result.Canceled)
|
||||
{
|
||||
await LoadAddresses();
|
||||
await AuthService.RefreshTokenAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OpenEditAddressDialog(CustomerAddressModel address)
|
||||
@@ -80,6 +84,7 @@ public partial class Addresses : ComponentBase
|
||||
await UserAddressContract.DeleteCustomerAddressAsync(new() { Id = id });
|
||||
Snackbar.Add("آدرس حذف شد.", Severity.Success);
|
||||
await LoadAddresses();
|
||||
await AuthService.RefreshTokenAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -333,6 +333,7 @@ public partial class Index
|
||||
if (!result.Canceled)
|
||||
{
|
||||
await LoadAddresses();
|
||||
await AuthService.RefreshTokenAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,6 +386,7 @@ public partial class Index
|
||||
});
|
||||
Snackbar.Add("آدرس با موفقیت حذف شد.", Severity.Success);
|
||||
await LoadAddresses();
|
||||
await AuthService.RefreshTokenAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -491,11 +493,6 @@ public partial class Index
|
||||
Snackbar.Add("لطفا اطلاعات شخصی خود را تکمیل کنید. (تاریخ تولد وارد نشده)", Severity.Error);
|
||||
return;
|
||||
}
|
||||
if (!_addresses.Any())
|
||||
{
|
||||
Snackbar.Add("آدرس محل سکونت شما الزامی است!", Severity.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var url = "https://dayadiamond.ir/profile/creditpurchase/?merchantcode=56146364";
|
||||
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
|
||||
|
||||
@@ -35,7 +35,11 @@ public partial class CheckoutSummary : ComponentBase
|
||||
await AuthDialogService.ShowAuthDialogAsync();
|
||||
}
|
||||
await Cart.EnsureInitializedAsync();
|
||||
var userInfo = await AuthService.GetUserAuthInfo();
|
||||
if (userInfo.HasAddress)
|
||||
await LoadAddresses();
|
||||
else
|
||||
_addresses = new();
|
||||
await LoadWalletBalance();
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ public class AuthService
|
||||
var isSignMainContractStr = claims.FirstOrDefault(c => c.key == "IsSignMainContract").value;
|
||||
var hasPurchasedPackageStr = claims.FirstOrDefault(c => c.key == "HasPurchasedPackage").value;
|
||||
var isClubMemberActiveStr = claims.FirstOrDefault(c => c.key == "IsClubMemberActive").value;
|
||||
var hasAddressStr = claims.FirstOrDefault(c => c.key == "HasAddress").value;
|
||||
|
||||
_userAuthInfo.UserId = long.TryParse(userIdStr, out var userId) ? userId : 0;
|
||||
_userAuthInfo.FirstName = firstName ?? string.Empty;
|
||||
@@ -88,6 +89,7 @@ public class AuthService
|
||||
_userAuthInfo.IsSignMainContract = bool.TryParse(isSignMainContractStr, out var isSignMainContract) && isSignMainContract;
|
||||
_userAuthInfo.HasPurchasedPackage = bool.TryParse(hasPurchasedPackageStr, out var hasPurchased) && hasPurchased;
|
||||
_userAuthInfo.IsClubMemberActive = bool.TryParse(isClubMemberActiveStr, out var isClubActive) && isClubActive;
|
||||
_userAuthInfo.HasAddress = bool.TryParse(hasAddressStr, out var hasAddress) && hasAddress;
|
||||
}
|
||||
|
||||
private async Task<List<(string key, string value)>?> GetTokenClaimsAsync()
|
||||
|
||||
@@ -11,4 +11,5 @@ public class UserAuthInfo
|
||||
public bool IsSignMainContract { get; set; }
|
||||
public bool HasPurchasedPackage { get; set; }
|
||||
public bool IsClubMemberActive { get; set; }
|
||||
public bool HasAddress { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user