feat: add top-seller product sections to landing page with guest browsing support
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 3m10s

- Add two sections to landing page (Index.razor) below the hero:
  - Top 6 best-selling regular products (3-per-row grid)
  - Top 6 best-selling discount store products (3-per-row grid)
  - Each section has a 'More' button linking to /products and /discount-store
- Add GuestActionGate utility service: wraps auth-required actions; shows
  login modal for guests and resumes the original action after successful login
- Register GuestActionGate as scoped service in ConfigureServices
- Add GetTopSellingAsync(count) to ProductService and DiscountProductService
- Add optional sortBy parameter to DiscountProductService.GetProductsAsync
- Hybridize all product pages for guest browsing:
  - Store/Products, Store/ProductDetail: wrap AddToCart with GuestActionGate
  - DiscountStore/Products, DiscountStore/ProductDetail: wrap AddToCart with GuestActionGate
  - Store/Cart, DiscountStore/Cart, Store/CheckoutSummary: soft auth gate on page init
- Fix MembershipPage membership benefit text to be package-agnostic

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
masoodafar-web
2026-05-13 19:48:14 +03:30
parent a1d67c5865
commit 231da2cbaa
15 changed files with 299 additions and 10 deletions
@@ -14,6 +14,8 @@ public partial class CheckoutSummary : ComponentBase
[Inject] private VATService VAT { get; set; } = default!;
[Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!;
[Inject] private UserOrderContract.UserOrderContractClient UserOrderContract { get; set; } = default!;
[Inject] private AuthDialogService AuthDialogService { get; set; } = default!;
[Inject] private AuthService AuthService { get; set; } = default!;
// Snackbar and Navigation are injected via _Imports.razor
private List<CustomerAddressModel> _addresses = new();
@@ -27,6 +29,10 @@ public partial class CheckoutSummary : ComponentBase
protected override async Task OnInitializedAsync()
{
if (!await AuthService.IsAuthenticatedAsync())
{
await AuthDialogService.ShowAuthDialogAsync();
}
// لود سبد خرید (فقط اگر کاربر لاگین کرده باشد)
await Cart.EnsureInitializedAsync();
await LoadAddresses();