- Changed GW_URL and GwUrl in frontoffice-deployment.yaml and Dockerfile to use the internal service URL http://cms-svc:8080 for the staging environment.
- Enhanced ConfigureServices to handle HTTP/1.1 for gRPC when using the internal service URL, ensuring compatibility with Kestrel's requirements.
- Added GW_URL and GwUrl environment variables in frontoffice-deployment.yaml and Dockerfile for consistent gateway URL configuration.
- Updated AddGrpcServices method to resolve gateway URL from both environment variables, ensuring proper error handling for missing values.
- Modified TokenNotificationService to prioritize GW_URL over GwUrl for improved configuration flexibility.
- Removed CmsServerBaseUrl utility class and updated references to directly access GwUrl from configuration.
- Adjusted frontoffice-deployment.yaml to remove CmsInternalBaseUrl environment variable.
- Updated appsettings for staging and main environments to reflect the correct CMS service URLs.
- Ensured consistent handling of GwUrl in TokenNotificationService and AddGrpcServices methods.
- Replace direct access to configuration for GwUrl with CmsServerBaseUrl.Resolve in AddGrpcServices and TokenNotificationService.
- Ensure proper error handling for missing GwUrl and add support for optional bypass of public TLS using CmsInternalBaseUrl.
- Adjust channel credentials based on whether the base URL is HTTPS or not.
- 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>
- NuGet.config: nuget.org for standard packages, local nupkg for proto
- Dockerfile: COPY nupkg/ before restore
- CI: build proto from CMS source before Docker build
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