feat: add per-org SMS wallet with adm panel and header credit

Bill all platform SMS (including OTP), allow negative balance with manual/auto cutoffs, and support own-panel bypass without wallet debit.
This commit is contained in:
2026-10-19 15:55:48 +03:30
parent f15ebb72ea
commit f5d68d83fc
42 changed files with 2073 additions and 121 deletions
+3
View File
@@ -22,6 +22,8 @@ const pageTitle = computed(() => {
return 'کاربران';
case 'adm-admins':
return 'ادمین‌ها';
case 'adm-sms':
return 'پیامک';
default:
return 'سوپرادمین';
}
@@ -31,6 +33,7 @@ const tabs = [
{ name: 'adm-dashboard', label: 'خانه', icon: 'home' as const },
{ name: 'adm-organizations', label: 'محیط‌ها', icon: 'building' as const },
{ name: 'adm-users', label: 'کاربران', icon: 'users' as const },
{ name: 'adm-sms', label: 'پیامک', icon: 'mail' as const },
{ name: 'adm-admins', label: 'ادمین‌ها', icon: 'lock' as const },
];
+3
View File
@@ -10,6 +10,7 @@ import QuickCreate from '@/components/QuickCreate.vue';
import OrgSwitcher from '@/components/OrgSwitcher.vue';
import NavHubPanel from '@/components/nav/NavHubPanel.vue';
import GamificationToaster from '@/components/gamification/GamificationToaster.vue';
import SmsHeaderWallet from '@/components/SmsHeaderWallet.vue';
import { NAV_HUBS, type NavHubDef, type NavHubKey } from '@/lib/nav-hubs';
import type {
ActivitySummaryDto,
@@ -769,6 +770,7 @@ onUnmounted(() => {
<BrandName lang="en" />
</div>
<div class="top-tools">
<SmsHeaderWallet />
<button class="round-btn" type="button" aria-label="اعلان‌ها" @click="toggleNotif">
<UiIcon name="bell" :size="18" />
<span v-if="hasUnread" class="badge">{{ toFaDigits(unreadCount) }}</span>
@@ -805,6 +807,7 @@ onUnmounted(() => {
</form>
<div class="topbar-actions">
<SmsHeaderWallet />
<RouterLink class="round-btn accent" :to="{ name: 'notes' }" title="هوش مصنوعی">
<UiIcon name="sparkle" :size="18" />
</RouterLink>