Phase 8c: FO Package pages — Customer RPCs + dynamic features

- NuGet: 0.0.182 → 0.0.185 + local feed source
- PackageDetail: GetPackageAsync → GetCustomerPackageDetailsAsync
  Features & specs now driven by API (PackageFeature) not hardcoded
- Packages.razor: Un-excluded from build, dynamic feature bullets
  from CustomerPackageModel (DiscountMultiplier, MagicWallet, etc.)
- PackageService: Enriched PackageDto with 8 new package fields
  GetUserPackageStatusAsync connected to real RPC (was stub)
This commit is contained in:
masoodafar-web
2026-02-26 17:52:37 +03:30
parent 0bbc11e82c
commit d71d463668
5 changed files with 109 additions and 56 deletions
@@ -10,7 +10,15 @@ public record PackageDto(
string Title,
string Description,
string ImageUrl,
long Price)
long Price,
long ActivationFee = 0,
double DiscountMultiplier = 0,
double MagicWalletMultiplier = 0,
long MagicWalletMaxDeposit = 0,
long MagicWalletMaxCredit = 0,
bool IsBasePackage = false,
bool SupportsDayaPurchase = false,
bool SupportsDirectPurchase = false)
{
public string FormattedPrice => string.Format("{0:N0} تومان", Price);
}
@@ -56,7 +64,15 @@ public class PackageService
m.Title,
m.Description,
m.ImagePath,
m.Price))
m.Price,
m.ActivationFee,
m.DiscountMultiplier,
m.MagicWalletMultiplier,
m.MagicWalletMaxDeposit,
m.MagicWalletMaxCredit,
m.IsBasePackage,
m.SupportsDayaPurchase,
m.SupportsDirectPurchase))
.ToList();
}
catch (Exception ex)
@@ -100,16 +116,32 @@ public class PackageService
/// <summary>
/// Get user's package purchase status
/// </summary>
public Task<UserPackageStatusDto> GetUserPackageStatusAsync(CancellationToken ct = default)
public async Task<UserPackageStatusDto> GetUserPackageStatusAsync(CancellationToken ct = default)
{
// TODO: Connect to GetUserPackageStatus RPC when available in FrontOffice.BFF
return Task.FromResult(new UserPackageStatusDto(
HasPurchasedPackage: false,
PackageTitle: null,
PurchaseMethod: null,
IsClubMemberActive: false,
WalletBalance: 0,
CanActivateClubMembership: false,
PurchaseDate: null));
try
{
var response = await _client.GetUserPackageStatusAsync(
new GetUserPackageStatusRequest(), cancellationToken: ct);
return new UserPackageStatusDto(
HasPurchasedPackage: response.HasPurchasedPackage,
PackageTitle: null,
PurchaseMethod: response.PackagePurchaseMethod,
IsClubMemberActive: response.IsClubMemberActive,
WalletBalance: response.WalletBalance,
CanActivateClubMembership: response.CanActivateClubMembership,
PurchaseDate: response.LastPurchaseDate?.ToDateTime());
}
catch
{
return new UserPackageStatusDto(
HasPurchasedPackage: false,
PackageTitle: null,
PurchaseMethod: null,
IsClubMemberActive: false,
WalletBalance: 0,
CanActivateClubMembership: false,
PurchaseDate: null);
}
}
}