From 8e98c50bdf8f190d4deafdfbfd0cb136c214b6c0 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sat, 8 Aug 2026 23:59:36 +0330 Subject: [PATCH] feat(wallet): enhance ChargeCreditWallet and Wallet components with magic ceiling consent logic - Added new logic to handle user consent for charging without a magic multiplier when the magic wallet ceiling is full. - Updated the ChargeCreditWallet component to display alerts and prompts based on the user's magic wallet status and consent. - Enhanced the Wallet component to conditionally render buttons and alerts related to the magic wallet ceiling status. - Improved user feedback in the InsufficientCreditDialog to guide users on charging options based on their wallet status. These changes enhance the user experience by providing clear instructions and options for charging wallets under specific conditions. --- .../Pages/Profile/ChargeCreditWallet.razor | 20 ++++- .../Pages/Profile/ChargeCreditWallet.razor.cs | 85 ++++++++++++++++--- .../Pages/Profile/MagicWallet.razor | 19 ++++- .../Pages/Profile/Wallet.razor | 24 +++++- .../Pages/Profile/Wallet.razor.cs | 3 + .../Pages/Store/CheckoutSummary.razor.cs | 18 +++- .../Shared/InsufficientCreditDialog.razor | 53 ++++++++++-- 7 files changed, 194 insertions(+), 28 deletions(-) diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor index eaab334..34a492a 100644 --- a/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor @@ -83,7 +83,18 @@ } - else if (_authLoaded) + else if (_authLoaded && _needsMagicCeilingConsent && !_allowNormalDespiteMagic && !_redirectingToMagic) + { + + + + + سقف شارژ جادویی پر است. برای شارژ بدون ضریب باید تأیید کنید... + + + + } + else if (ShowChargeForm) { @@ -91,6 +102,13 @@ شارژ موجودی اصلی + @if (_allowNormalDespiteMagic) + { + + این شارژ بدون ضریب جادویی است (۱:۱). سقف واریز جادویی شما در این دور پر شده است. + + } + مبلغ وارد شده (به تومان) از طریق درگاه پرداخت به موجودی اصلی شما اضافه می‌شود. از موجودی اصلی برای خرید از فروشگاه عادی و پرداخت سفارش استفاده می‌شود. diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor.cs b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor.cs index bac834d..8b7ffff 100644 --- a/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor.cs +++ b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor.cs @@ -17,6 +17,9 @@ public partial class ChargeCreditWallet : ComponentBase private bool _hasPurchasedPackage; private bool _authLoaded; private bool _redirectingToMagic; + private bool _allowNormalDespiteMagic; + private bool _needsMagicCeilingConsent; + private bool _magicConsentPrompted; private readonly long[] _presetAmounts = { 500_000, 1_000_000, 5_000_000, 10_000_000, 20_000_000, 50_000_000 }; @@ -29,6 +32,12 @@ public partial class ChargeCreditWallet : ComponentBase [SupplyParameterFromQuery(Name = "returnUrl")] public string? ReturnUrlQueryParam { get; set; } + private bool ShowChargeForm => + _authLoaded + && _isClubMemberActive + && !_redirectingToMagic + && (!_needsMagicCeilingConsent || _allowNormalDespiteMagic); + protected override async Task OnInitializedAsync() { _paymentResult = PaymentQueryParam; @@ -55,16 +64,20 @@ public partial class ChargeCreditWallet : ComponentBase _authLoaded = true; } - // اگر کیف پول جادویی فعال است، فرم شارژ ۱:۱ نشان داده نشود - if (_isClubMemberActive && await TryRedirectIfMagicWalletAsync()) - return; + if (_isClubMemberActive) + await EvaluateMagicWalletGateAsync(promptConsent: false); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && !string.IsNullOrEmpty(_pendingReturnUrl) && _isClubMemberActive && !_redirectingToMagic) - { await CreditChargeNavigation.SaveReturnUrlAsync(JSRuntime, _pendingReturnUrl); + + if (firstRender && _needsMagicCeilingConsent && !_allowNormalDespiteMagic && !_magicConsentPrompted) + { + _magicConsentPrompted = true; + await PromptMagicCeilingConsentAsync(); + StateHasChanged(); } await base.OnAfterRenderAsync(firstRender); @@ -80,7 +93,10 @@ public partial class ChargeCreditWallet : ComponentBase return; } - if (await TryRedirectIfMagicWalletAsync()) + if (await EvaluateMagicWalletGateAsync(promptConsent: true)) + return; + + if (!_allowNormalDespiteMagic && _needsMagicCeilingConsent) return; if (_chargeAmount <= 0 || _isProcessing) return; @@ -122,25 +138,47 @@ public partial class ChargeCreditWallet : ComponentBase } /// - /// اگر WalletMode جادویی باشد، پیام می‌دهد و به صفحه شارژ کیف جادویی هدایت می‌کند. + /// Magic با ظرفیت باقی‌مانده → ریدایرکت به MagicWallet. + /// Magic با سقف پر → نیاز به رضایت برای شارژ ۱:۱. + /// true یعنی مسیر شارژ فعلی باید متوقف شود. /// - private async Task TryRedirectIfMagicWalletAsync() + private async Task EvaluateMagicWalletGateAsync(bool promptConsent) { + if (_allowNormalDespiteMagic) + return false; + try { var status = await WalletService.GetMagicWalletStatusAsync(); if (status.WalletMode != 1) + { + _needsMagicCeilingConsent = false; return false; + } - var multiplier = status.MagicMultiplier > 0 ? status.MagicMultiplier : 2.5; - var multiplierText = multiplier.ToString("0.#"); + if (status.MagicRemainingDeposit > 0) + { + var multiplier = status.MagicMultiplier > 0 ? status.MagicMultiplier : 2.5; + var multiplierText = multiplier.ToString("0.#"); - _redirectingToMagic = true; - Snackbar.Add( - $"کیف پول شما در حالت جادویی است. شارژ از این صفحه موجودی را چندبرابر نمی‌کند. برای دریافت ضریب جادویی (×{multiplierText}) به صفحه شارژ کیف پول جادویی هدایت می‌شوید.", - Severity.Info); + _redirectingToMagic = true; + _needsMagicCeilingConsent = false; + Snackbar.Add( + $"کیف پول شما در حالت جادویی است. شارژ از این صفحه موجودی را چندبرابر نمی‌کند. برای دریافت ضریب جادویی (×{multiplierText}) به صفحه شارژ کیف پول جادویی هدایت می‌شوید.", + Severity.Info); + + Navigation.NavigateTo(RouteConstants.Profile.MagicWallet); + return true; + } + + _needsMagicCeilingConsent = true; + + if (promptConsent) + { + await PromptMagicCeilingConsentAsync(); + return !_allowNormalDespiteMagic; + } - Navigation.NavigateTo(RouteConstants.Profile.MagicWallet); return true; } catch @@ -150,6 +188,25 @@ public partial class ChargeCreditWallet : ComponentBase } } + private async Task PromptMagicCeilingConsentAsync() + { + var confirmed = await DialogService.ShowMessageBox( + "شارژ بدون ضریب جادویی", + "سقف شارژ کیف پول جادویی شما در این دور پر شده است. شارژ از این صفحه بدون ضریب (۱:۱) به موجودی اضافه می‌شود و ضریب جادویی اعمال نمی‌شود. آیا مایلید ادامه دهید؟", + yesText: "ادامه شارژ بدون ضریب", + cancelText: "انصراف"); + + if (confirmed == true) + { + _allowNormalDespiteMagic = true; + _redirectingToMagic = false; + return; + } + + _redirectingToMagic = true; + Navigation.NavigateTo(RouteConstants.Profile.MagicWallet); + } + private async Task ContinueShoppingAsync() { var returnUrl = await CreditChargeNavigation.GetReturnUrlAsync(JSRuntime); diff --git a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor index 19d4e2d..89e973b 100644 --- a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor @@ -166,8 +166,23 @@ else { - سقف شارژ جادویی در این دور پر شده است. - با خرج کردن موجودی و خرید مجدد پکیج، سقف ریست می‌شود. + + + سقف شارژ جادویی در این دور پر شده است. + با خرج کردن موجودی و خرید مجدد پکیج، سقف ریست می‌شود. + + + اگر برای تکمیل خرید به موجودی بیشتری نیاز دارید، می‌توانید به‌صورت استثنایی کیف اصلی را بدون ضریب (۱:۱) شارژ کنید. + + + شارژ عادی بدون ضریب + + } diff --git a/src/FrontOffice.Main/Pages/Profile/Wallet.razor b/src/FrontOffice.Main/Pages/Profile/Wallet.razor index e13abee..5da6575 100644 --- a/src/FrontOffice.Main/Pages/Profile/Wallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/Wallet.razor @@ -52,9 +52,27 @@ Class="rounded-lg"> شارژ کیف‌پول جادویی - - کیف پول شما در حالت جادویی است؛ شارژ از مسیر جادویی با ضریب چندبرابر اعمال می‌شود. - + @if (_magicCeilingFull) + { + + سقف شارژ جادویی این دور پر است. در صورت نیاز می‌توانید به‌صورت استثنایی بدون ضریب شارژ کنید. + + + شارژ عادی بدون ضریب + + } + else + { + + کیف پول شما در حالت جادویی است؛ شارژ از مسیر جادویی با ضریب چندبرابر اعمال می‌شود. + + } } else { diff --git a/src/FrontOffice.Main/Pages/Profile/Wallet.razor.cs b/src/FrontOffice.Main/Pages/Profile/Wallet.razor.cs index f20a00c..491e09d 100644 --- a/src/FrontOffice.Main/Pages/Profile/Wallet.razor.cs +++ b/src/FrontOffice.Main/Pages/Profile/Wallet.razor.cs @@ -15,6 +15,7 @@ public partial class Wallet : ComponentBase private bool _isClubMemberActive; private bool _hasPurchasedPackage; private bool _isMagicWallet; + private bool _magicCeilingFull; protected override async Task OnInitializedAsync() { @@ -34,10 +35,12 @@ public partial class Wallet : ComponentBase { var magicStatus = await WalletService.GetMagicWalletStatusAsync(); _isMagicWallet = magicStatus.WalletMode == 1; + _magicCeilingFull = _isMagicWallet && magicStatus.MagicRemainingDeposit <= 0; } catch { _isMagicWallet = false; + _magicCeilingFull = false; } var b = await WalletService.GetBalancesAsync(); diff --git a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs index d199997..8437093 100644 --- a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs +++ b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs @@ -127,6 +127,8 @@ public partial class CheckoutSummary : ComponentBase var shortfall = totalRequired - walletBalance; var allowCharge = false; var hasPurchasedPackage = false; + var isMagicWallet = false; + var magicCeilingFull = false; try { var userInfo = await AuthService.GetUserAuthInfo(); @@ -138,13 +140,27 @@ public partial class CheckoutSummary : ComponentBase allowCharge = false; } + try + { + var magicStatus = await WalletService.GetMagicWalletStatusAsync(); + isMagicWallet = magicStatus.WalletMode == 1; + magicCeilingFull = isMagicWallet && magicStatus.MagicRemainingDeposit <= 0; + } + catch + { + isMagicWallet = false; + magicCeilingFull = false; + } + var parameters = new DialogParameters { { x => x.CurrentBalance, walletBalance }, { x => x.RequiredAmount, totalRequired }, { x => x.ShortfallAmount, shortfall }, { x => x.AllowChargeCredit, allowCharge }, - { x => x.HasPurchasedPackage, hasPurchasedPackage } + { x => x.HasPurchasedPackage, hasPurchasedPackage }, + { x => x.IsMagicWallet, isMagicWallet }, + { x => x.MagicCeilingFull, magicCeilingFull } }; var dialog = await DialogService.ShowAsync( diff --git a/src/FrontOffice.Main/Shared/InsufficientCreditDialog.razor b/src/FrontOffice.Main/Shared/InsufficientCreditDialog.razor index b55951d..b0fb437 100644 --- a/src/FrontOffice.Main/Shared/InsufficientCreditDialog.razor +++ b/src/FrontOffice.Main/Shared/InsufficientCreditDialog.razor @@ -11,9 +11,24 @@ @if (AllowChargeCredit) { - - برای تکمیل این سفارش، موجودی اصلی شما کافی نیست. می‌توانید کیف پول را شارژ کنید و سپس سفارش را ثبت کنید. - + @if (IsMagicWallet && !MagicCeilingFull) + { + + برای تکمیل این سفارش موجودی شما کافی نیست. کیف پول شما در حالت جادویی است؛ برای دریافت ضریب، از مسیر شارژ جادویی اقدام کنید. + + } + else if (IsMagicWallet && MagicCeilingFull) + { + + سقف شارژ جادویی شما در این دور پر است. می‌توانید به‌صورت استثنایی کیف اصلی را بدون ضریب (۱:۱) شارژ کنید. + + } + else + { + + برای تکمیل این سفارش، موجودی اصلی شما کافی نیست. می‌توانید کیف پول را شارژ کنید و سپس سفارش را ثبت کنید. + + } } else { @@ -46,10 +61,10 @@ @if (AllowChargeCredit) { - شارژ حساب اصلی + @ChargeButtonLabel } else if (!HasPurchasedPackage) @@ -93,9 +108,33 @@ [Parameter] public bool HasPurchasedPackage { get; set; } + [Parameter] + public bool IsMagicWallet { get; set; } + + /// سقف واریز جادویی این دور پر شده است. + [Parameter] + public bool MagicCeilingFull { get; set; } + + private string ChargeButtonLabel => + IsMagicWallet && !MagicCeilingFull + ? "شارژ کیف جادویی" + : IsMagicWallet && MagicCeilingFull + ? "شارژ عادی بدون ضریب (سقف جادویی پر است)" + : "شارژ حساب اصلی"; + private void Cancel() => MudDialog.Cancel(); - private void GoToCharge() => MudDialog.Close(DialogResult.Ok(ShortfallAmount)); + private void GoToCharge() + { + if (IsMagicWallet && !MagicCeilingFull) + { + MudDialog.Cancel(); + Navigation.NavigateTo(RouteConstants.Profile.MagicWallet); + return; + } + + MudDialog.Close(DialogResult.Ok(ShortfallAmount)); + } private void GoToPackages() {