feat(admin): subscription expiry modals and once-per-session SMS warning

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-14 16:37:28 +03:30
co-authored by Cursor
parent 5dd9f7db96
commit 82dc6b82d8
9 changed files with 434 additions and 12 deletions
+38 -2
View File
@@ -10,6 +10,32 @@ const EMPTY_DEPOSIT: SmsDepositInfo = {
note: ''
}
const NEGATIVE_WARNING_SESSION_KEY = 'khanegi_admin_sms_negative_warning_shown'
function wasNegativeWarningShownThisSession() {
try {
return sessionStorage.getItem(NEGATIVE_WARNING_SESSION_KEY) === '1'
} catch {
return false
}
}
function markNegativeWarningShownThisSession() {
try {
sessionStorage.setItem(NEGATIVE_WARNING_SESSION_KEY, '1')
} catch {
// ignore storage failures
}
}
function clearNegativeWarningShownThisSession() {
try {
sessionStorage.removeItem(NEGATIVE_WARNING_SESSION_KEY)
} catch {
// ignore storage failures
}
}
/** وضعیت کیف پول پیامک برای نمایش «اعتبار پیامک» در هدر (همه ادمین‌ها). */
export const useSmsWalletStore = defineStore('smsWallet', () => {
const userStore = useUserStore()
@@ -19,7 +45,7 @@ export const useSmsWalletStore = defineStore('smsWallet', () => {
const deposit = ref<SmsDepositInfo>({ ...EMPTY_DEPOSIT })
const loaded = ref(false)
const loading = ref(false)
/** هشدار موجودی منفی — با هر refresh اگر هنوز منفی باشد دوباره باز می‌شود */
/** هشدار موجودی منفی — فقط یک‌بار در هر باز شدن نشست ادمین */
const negativeWarningVisible = ref(false)
/** ویجت فقط وقتی billing/پنل پیامک فعال است نمایش داده می‌شود. */
@@ -40,7 +66,16 @@ export const useSmsWalletStore = defineStore('smsWallet', () => {
isBlocked.value = res.is_blocked
deposit.value = res.deposit ?? { ...EMPTY_DEPOSIT }
loaded.value = true
negativeWarningVisible.value = res.balance < 0
if (res.balance >= 0) {
negativeWarningVisible.value = false
clearNegativeWarningShownThisSession()
} else if (!wasNegativeWarningShownThisSession()) {
negativeWarningVisible.value = true
markNegativeWarningShownThisSession()
} else {
negativeWarningVisible.value = false
}
} catch {
// خطای موجودی نباید مزاحم کاربر شود؛ ویجت در صورت نبود داده مخفی می‌ماند
} finally {
@@ -50,6 +85,7 @@ export const useSmsWalletStore = defineStore('smsWallet', () => {
function dismissNegativeWarning() {
negativeWarningVisible.value = false
markNegativeWarningShownThisSession()
}
return {