- Modified `GetTopSellingAsync` methods in `ProductService` and `DiscountProductService` to include an optional `inStock` parameter for filtering products based on availability.
- Introduced a constant for the top product count in `Index.razor.cs` to improve maintainability and readability.
- Updated the product retrieval logic in `Index.razor.cs` to utilize the new in-stock filtering feature.
These changes enhance the product listing functionality by allowing users to view only in-stock top-selling products, improving the overall shopping experience.
- Updated references to `jsRuntime` to `JSRuntime` for consistency across the ChargeCreditWallet component.
- Improved the clarity of the code by ensuring uniform naming conventions in the handling of return URLs.
These changes enhance code readability and maintainability in the ChargeCreditWallet functionality.
- Added support for return URL handling in ChargeCreditWallet to improve user experience after payment.
- Introduced a "Continue Shopping" button that allows users to navigate back to their previous shopping session after successfully charging their wallet.
- Updated the component to manage pending return URLs and ensure they are saved and retrieved correctly.
These changes enhance the functionality of the ChargeCreditWallet page, providing a smoother transition for users post-transaction.
- Introduced methods for initiating and verifying credit wallet charges in the WalletService.
- Updated PaymentCallback.razor to handle credit wallet charge verification.
- Added a button for charging the credit wallet in Wallet.razor.
- Updated route constants to include the new credit wallet charge route.
These changes enhance the wallet functionality by allowing users to charge their credit wallets and verify transactions seamlessly.
Updated the organization chart component to explicitly map network node properties to a flat array with camelCase keys. This change aligns the data structure with the BackOffice admin chart, enhancing consistency and clarity in the displayed information.
Gate payment callback with a semaphore and block double-clicks on checkout
to avoid sending multiple verify requests after gateway redirect.
Co-authored-by: Cursor <cursoragent@cursor.com>
Guests can browse products and product details for presentation purposes,
but prices are hidden behind a 'وارد شوید' prompt (lock icon).
Authenticated users see prices as before.
Affected pages:
- Landing page (Index): top-selling regular + discount sections
- Store/Products list
- Store/ProductDetail (desktop price + mobile sticky bar)
- DiscountStore/Products list
- DiscountStore/ProductDetail (full price box)
Each code-behind now checks AuthService.IsAuthenticatedAsync() on init
and stores the result in _isAuthenticated for use in the template.
Co-authored-by: Cursor <cursoragent@cursor.com>
Changed the text for best-selling products in both the main store and credit store sections to improve clarity and consistency. The previous titles "پرخریدترین محصولات فروشگاه" and "پرخریدترین محصولات فروشگاه اعتباری" have been updated to "محصولات پرفروش فروشگاه" and "محصولات پرفروش فروشگاه اعتباری" respectively.
- 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>
Root cause: FrontOffice was converting Toman→Rial (×10) before sending to CMS,
but CMS ZarinPalService already does Toman→Rial conversion internally.
This caused double ×10 = amounts shown 10x higher in payment gateway.
Fixes:
- MagicWallet.razor.cs: remove ×10 conversion, send _chargeAmount (Toman) directly
- MagicWallet.razor: fix Max field (no /10), fix preset filter (no ×10)
- MagicWallet.razor.cs: fix FormatPrice — values from CMS are Toman, not Rial
- ChargeDiscountWallet.razor.cs: same fix — send Toman directly
- ClubMembershipContractDialog.razor: fix Price display (no /10)
1. Toman/Rial mismatch — Price from server is in Rial, now divides by 10 for correct Toman display
2. ضریب تخفیف → ضریب اعتبار label change in dialog + packages page
3. Back button already functional (ArrowForward in TitleContent) — verified
4. HTML rendering in package description via MarkupString
- حذف متن hardcoded 'پکیج پایه ۵۶ میلیون تومان' و دیالوگ inline
- ایجاد PackagePurchaseDialog — کامپوننت مستقل 2 مرحلهای:
مرحله ۱: نمایش کاشیهای پکیج (ریسپانسیو ۲-۳ تایی)
مرحله ۲: انتخاب روش پرداخت (درگاه بانکی / دایا الماس)
- دایا الماس فقط برای پکیج پایه + دور اول نمایش داده میشه
- پکیجها داینامیک از API بارگذاری میشن
- تغییر متن CTA از 'شروع فرآیند تامین اعتبار' به 'تهیه پکیج'
- تغییر متن راهنما از 'پکیج پایه را تهیه کنید' به 'یکی از پکیجها را تهیه کنید'
- CSS: hover effects + badge + responsive tiles
F6: MagicWallet.razor — جایگزینی ×2.5 و سقفهای ثابت با مقادیر از API
- WalletService: MagicMultiplier + MagicMaxCredit از gRPC response
- Index.razor.cs: 'شارژ ×2.5' → 'شارژ چندبرابری' (تایل داشبورد)
F7: ChargeDiscountWallet.razor — Max از 100M تومان به 1B تومان
اصلاح rename:
- ConfigureServices: UserWalletChangeLog → UserWalletHistory
- WalletService: اصلاح تمام رفرنسها
NuGet: v0.0.189
T4.2: Conditional Payment in Checkout
- Load package flags via PackageService.GetAllPackagesAsync
- Respect SupportsDirectPurchase/SupportsDayaPurchase flags
- Add Daya loan payment button when supported
- Show alert when no payment method available
T4.3: MyPackages Re-Purchase Logic
- Load MagicWallet status to detect cycle completion
- Show re-purchase CTA when magic cycle is complete
- Show magic wallet progress bar during active cycle
- Display deposit progress, remaining, and credited amounts
F3: PV Display in Order Details
- Add CalculateOrderPVAsync to OrderService
- Show per-product PV and total PV in Store OrderDetail
- Update NuGet to v0.0.188
- 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)
- MyPackages.razor: dynamic PackageTitle from DTO instead of hardcoded 'پکیج طلایی'
- Packages.razor: generic text for purchase status and info section
- PackageService.cs: add PackageTitle to UserPackageStatusDto record
- ChargeDiscountWallet: active payment button with StartDiscountCharge
- MagicWallet: active payment button with StartMagicCharge
- Index: both branch buttons call DirectPayment with loading state
- Add ChargeDiscountWallet.razor page with charge form and preset amounts
- Add ChargeDiscountWallet.razor.cs code-behind with gateway redirect logic
- Add InitiateDiscountChargeAsync client method in WalletService
- Add ChargeDiscountWallet route constant
- Add charge button link on main Wallet page
- FrontOffice.Main.csproj: switch to ProjectReference for CMS Protobuf
- MagicWallet.razor.cs: update default record with PurchaseCycleCount
- WalletService.cs: add PurchaseCycleCount to MagicWalletStatus record
- Profile/Index.razor.cs: load _purchaseCycleCount from MagicWalletStatus
- Profile/Index.razor: conditional purchase dialog (IPG vs Daya by cycle)
- Licenses.razor: fix grid column size xs=6
- ProductService: add GetProductsPagedAsync with PaginationState support
- Store/Products: replace load-all with page-by-page lazy loading (12 per page)
- DiscountStore/Products: replace pagination with lazy load (load more button)
- Both stores show 'load more' button + loading indicator + 'all shown' text
- initScrollAnimations ran only on firstRender when data wasn't loaded yet
- Items with fade-in-up class stayed invisible (opacity:0) after data render
- Now tracks _dataLoaded/_animationsInitialized flags to re-init JS after data loads
- Also fixes stat counter animations not running (stats were empty on firstRender)
- Index.razor.cs: load landing SettingsJson via SitePageSettingsService
- PopulateFromSettings(): parse trustBadges, steps, features, stats, testimonials, faqs from DB
- ResolveIcon(): dynamically resolve MudBlazor icons from icon name strings
- Index.razor: make hero text, section titles, CTA dynamic with fallback defaults
- All hardcoded data preserved as fallbacks when DB is unavailable
- Updated NuGet to Protobuf v0.0.179
- Added PaymentStatus to DiscountOrderSummary and DiscountOrderDetail records
- OrderDetail: show payment status chip (Pending/Success/Failed/Refunded)
- OrderDetail: show alert with re-order link for failed payments
- Orders: updated desktop table and mobile cards with PaymentStatus chips
- Added GetPaymentStatusText() and GetPaymentStatusColor() helpers