Add support panel UI, search filters, and money thousand separators.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { ArrowRightOutlined, MessageOutlined } from '@ant-design/icons-vue'
|
||||
import { ArrowRightOutlined, MessageOutlined, SearchOutlined } from '@ant-design/icons-vue'
|
||||
import api from '@/api/http'
|
||||
|
||||
type BalanceLevel = 'healthy' | 'warning' | 'critical' | 'unknown'
|
||||
@@ -23,10 +23,22 @@ type TenantRow = {
|
||||
const router = useRouter()
|
||||
const loadingList = ref(false)
|
||||
const tenants = ref<TenantRow[]>([])
|
||||
const q = ref('')
|
||||
|
||||
const filteredTenants = computed(() => {
|
||||
const term = q.value.trim().toLowerCase()
|
||||
if (!term) return tenants.value
|
||||
return tenants.value.filter(
|
||||
(t) =>
|
||||
t.nameFa.toLowerCase().includes(term) ||
|
||||
t.domain.toLowerCase().includes(term) ||
|
||||
t.slug.toLowerCase().includes(term),
|
||||
)
|
||||
})
|
||||
|
||||
const groupedTenants = computed(() => ({
|
||||
hamkar: tenants.value.filter((t) => t.product === 'hamkar'),
|
||||
khanegi: tenants.value.filter((t) => t.product === 'khanegi'),
|
||||
hamkar: filteredTenants.value.filter((t) => t.product === 'hamkar'),
|
||||
khanegi: filteredTenants.value.filter((t) => t.product === 'khanegi'),
|
||||
}))
|
||||
|
||||
function toneClass(level?: BalanceLevel) {
|
||||
@@ -60,10 +72,24 @@ onMounted(loadTenants)
|
||||
</a-button>
|
||||
<div style="flex: 1">
|
||||
<h1 class="page-title">پنل پیامکی</h1>
|
||||
<p class="page-sub">یک نسخه را انتخاب کنید تا کیف پول و تنظیمات SMS همان نسخه باز شود</p>
|
||||
<p class="page-sub">
|
||||
یک نسخه را انتخاب کنید تا کیف پول و تنظیمات SMS همان نسخه باز شود ·
|
||||
{{ filteredTenants.length }} مورد
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toolbar">
|
||||
<a-input
|
||||
v-model:value="q"
|
||||
allow-clear
|
||||
placeholder="جستجو نام، دامنه یا slug"
|
||||
style="flex: 1; min-width: 180px"
|
||||
>
|
||||
<template #prefix><SearchOutlined /></template>
|
||||
</a-input>
|
||||
</div>
|
||||
|
||||
<a-alert
|
||||
type="info"
|
||||
show-icon
|
||||
@@ -100,6 +126,7 @@ onMounted(loadTenants)
|
||||
<span>{{ t.sms?.balanceLabel }}</span>
|
||||
<small>{{ t.isBlocked ? 'مسدود' : t.domain }}</small>
|
||||
</button>
|
||||
<div v-if="!groupedTenants.hamkar.length" class="empty-hint">نسخهای نیست</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -121,6 +148,7 @@ onMounted(loadTenants)
|
||||
<span>{{ t.sms?.balanceLabel }}</span>
|
||||
<small>{{ t.isBlocked ? 'مسدود' : t.domain }}</small>
|
||||
</button>
|
||||
<div v-if="!groupedTenants.khanegi.length" class="empty-hint">نسخهای نیست</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
@@ -198,4 +226,10 @@ onMounted(loadTenants)
|
||||
box-shadow: 0 10px 22px rgba(23, 50, 77, 0.08);
|
||||
}
|
||||
.tenant-card small { direction: ltr; text-align: right; }
|
||||
.empty-hint {
|
||||
grid-column: 1 / -1;
|
||||
color: #94a3b8;
|
||||
padding: 12px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user