From 7e043b24be777b2ae654ed0341552ebc4e5407a2 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Sat, 8 Aug 2026 14:11:43 +0330 Subject: [PATCH] Show negative SMS wallet warning modal on admin page loads. Co-authored-by: Cursor --- src/components/SmsCreditWidget.vue | 10 +- src/components/SmsNegativeBalanceHost.vue | 27 +++++ src/components/SmsNegativeBalanceModal.vue | 115 +++++++++++++++++++++ src/core/layouts/BasicLayout.vue | 2 + src/store/smsWalletStore.ts | 13 ++- 5 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 src/components/SmsNegativeBalanceHost.vue create mode 100644 src/components/SmsNegativeBalanceModal.vue diff --git a/src/components/SmsCreditWidget.vue b/src/components/SmsCreditWidget.vue index 41d752c..8531c8b 100644 --- a/src/components/SmsCreditWidget.vue +++ b/src/components/SmsCreditWidget.vue @@ -212,11 +212,19 @@ watch(modalVisible, (open) => { if (open) showLabelHint.value = false }) +function onOpenChargeFromWarning() { + modalVisible.value = true +} + onMounted(() => { if (isCompactDesktop.value) startLabelHintLoop() + window.addEventListener('sms-open-charge-modal', onOpenChargeFromWarning) }) -onUnmounted(stopLabelHintTimers) +onUnmounted(() => { + stopLabelHintTimers() + window.removeEventListener('sms-open-charge-modal', onOpenChargeFromWarning) +}) diff --git a/src/core/layouts/BasicLayout.vue b/src/core/layouts/BasicLayout.vue index 6f908a5..75fdf99 100644 --- a/src/core/layouts/BasicLayout.vue +++ b/src/core/layouts/BasicLayout.vue @@ -90,6 +90,7 @@ + @@ -102,6 +103,7 @@ import { isMobile } from '@core/utils/is' import BaseSettings from '@core/layouts/BaseSettings.vue' import BasicMobileHeader from '@/components/BasicMobileHeader.vue' import BasicMobileBottomNav from '@/components/BasicMobileBottomNav.vue' +import SmsNegativeBalanceHost from '@/components/SmsNegativeBalanceHost.vue' const { prefixCls } = usePrefix('basic-layout') const layoutStore = useLayoutStore() diff --git a/src/store/smsWalletStore.ts b/src/store/smsWalletStore.ts index 2b18953..357e328 100644 --- a/src/store/smsWalletStore.ts +++ b/src/store/smsWalletStore.ts @@ -1,4 +1,5 @@ import { computed, ref } from 'vue' +import { defineStore } from 'pinia' import { getSmsWalletSummary, type SmsDepositInfo } from '@/api/smsPanel' import { useUserStore } from '@/store/userStore' @@ -18,6 +19,8 @@ export const useSmsWalletStore = defineStore('smsWallet', () => { const deposit = ref({ ...EMPTY_DEPOSIT }) const loaded = ref(false) const loading = ref(false) + /** هشدار موجودی منفی — با هر refresh اگر هنوز منفی باشد دوباره باز می‌شود */ + const negativeWarningVisible = ref(false) /** ویجت فقط وقتی billing/پنل پیامک فعال است نمایش داده می‌شود. */ const visible = computed(() => userStore.smsBillingEnabled) @@ -25,6 +28,7 @@ export const useSmsWalletStore = defineStore('smsWallet', () => { async function refresh() { if (!visible.value) { loaded.value = false + negativeWarningVisible.value = false return } if (loading.value) return @@ -36,6 +40,7 @@ export const useSmsWalletStore = defineStore('smsWallet', () => { isBlocked.value = res.is_blocked deposit.value = res.deposit ?? { ...EMPTY_DEPOSIT } loaded.value = true + negativeWarningVisible.value = res.balance < 0 } catch { // خطای موجودی نباید مزاحم کاربر شود؛ ویجت در صورت نبود داده مخفی می‌ماند } finally { @@ -43,6 +48,10 @@ export const useSmsWalletStore = defineStore('smsWallet', () => { } } + function dismissNegativeWarning() { + negativeWarningVisible.value = false + } + return { balance, isBlocked, @@ -50,6 +59,8 @@ export const useSmsWalletStore = defineStore('smsWallet', () => { loaded, loading, visible, - refresh + negativeWarningVisible, + refresh, + dismissNegativeWarning } })