Add support panel UI, search filters, and money thousand separators.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+56
-7
@@ -5,6 +5,7 @@ import {
|
||||
MessageOutlined,
|
||||
CloudServerOutlined,
|
||||
AppstoreAddOutlined,
|
||||
CustomerServiceOutlined,
|
||||
TeamOutlined,
|
||||
HomeOutlined,
|
||||
UserOutlined,
|
||||
@@ -52,12 +53,15 @@ type ExpiringPlugin = {
|
||||
}
|
||||
}
|
||||
|
||||
type ExpiringSupport = ExpiringPlugin
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
const tenants = ref<Tenant[]>([])
|
||||
const smsTenants = ref<Tenant[]>([])
|
||||
const expiringServers = ref<Tenant[]>([])
|
||||
const expiringPlugins = ref<ExpiringPlugin[]>([])
|
||||
const expiringSupports = ref<ExpiringSupport[]>([])
|
||||
|
||||
const hamkarCount = computed(() => tenants.value.filter((t) => t.product === 'hamkar').length)
|
||||
const khanegiCount = computed(() => tenants.value.filter((t) => t.product === 'khanegi').length)
|
||||
@@ -96,16 +100,19 @@ const modules = computed(() => [
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const [tenantsRes, lowestRes, expiringRes, pluginExpiringRes] = await Promise.all([
|
||||
api.get('/tenants'),
|
||||
api.get('/sms/lowest', { params: { limit: 5 } }),
|
||||
api.get('/servers/expiring', { params: { limit: 5 } }),
|
||||
api.get('/plugins/expiring', { params: { limit: 5 } }),
|
||||
])
|
||||
const [tenantsRes, lowestRes, expiringRes, pluginExpiringRes, supportExpiringRes] =
|
||||
await Promise.all([
|
||||
api.get('/tenants'),
|
||||
api.get('/sms/lowest', { params: { limit: 5 } }),
|
||||
api.get('/servers/expiring', { params: { limit: 5 } }),
|
||||
api.get('/plugins/expiring', { params: { limit: 5 } }),
|
||||
api.get('/support/expiring', { params: { limit: 5 } }),
|
||||
])
|
||||
tenants.value = tenantsRes.data
|
||||
smsTenants.value = lowestRes.data
|
||||
expiringServers.value = expiringRes.data
|
||||
expiringPlugins.value = pluginExpiringRes.data
|
||||
expiringSupports.value = supportExpiringRes.data
|
||||
} catch (e: any) {
|
||||
message.error(e?.response?.data?.message || 'خطا در دریافت آمار')
|
||||
} finally {
|
||||
@@ -137,6 +144,14 @@ function openPluginPanel(tenantId?: string) {
|
||||
router.push({ name: 'plugin-panel' })
|
||||
}
|
||||
|
||||
function openSupportPanel(tenantId?: string) {
|
||||
if (tenantId) {
|
||||
router.push({ name: 'support-tenant', params: { tenantId } })
|
||||
return
|
||||
}
|
||||
router.push({ name: 'support-panel' })
|
||||
}
|
||||
|
||||
function smsTone(level?: BalanceLevel) {
|
||||
switch (level) {
|
||||
case 'healthy':
|
||||
@@ -173,7 +188,7 @@ onMounted(load)
|
||||
<div class="login-kicker">داشبورد کنترل</div>
|
||||
<h1 class="page-title">سلام، خوش آمدید</h1>
|
||||
<p class="page-sub">
|
||||
از اینجا به پنل پیامکی، سرور، افزونه، مدیران و نسخههای همکار / خانگی دسترسی دارید.
|
||||
از اینجا به پنل پیامکی، سرور، افزونه، پشتیبانی، مدیران و نسخههای همکار / خانگی دسترسی دارید.
|
||||
</p>
|
||||
|
||||
<a-spin :spinning="loading">
|
||||
@@ -285,6 +300,40 @@ onMounted(load)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="module-card support sms-dashboard-card" @click="openSupportPanel()">
|
||||
<div>
|
||||
<div class="icon-wrap">
|
||||
<CustomerServiceOutlined />
|
||||
</div>
|
||||
<h3>پنل پشتیبانی</h3>
|
||||
<p>پشتیبانیهایی که اعتبارشان رو به پایان است (قابل ثبت رایگان)</p>
|
||||
</div>
|
||||
<div class="sms-mini-grid">
|
||||
<button
|
||||
v-for="item in expiringSupports"
|
||||
:key="item.id"
|
||||
type="button"
|
||||
class="sms-mini-card"
|
||||
:class="serverTone(item.expiryLevel)"
|
||||
@click.stop="openSupportPanel(item.tenantId)"
|
||||
>
|
||||
<strong>{{ item.tenant?.nameFa }}</strong>
|
||||
<span>{{ item.name }}</span>
|
||||
<small>{{ item.expiryLabel || 'نامشخص' }}</small>
|
||||
</button>
|
||||
<div v-if="!expiringSupports.length" class="sms-mini-empty">
|
||||
پشتیبانی نزدیکانقضا یا بدون تاریخ ثبتشده نیست
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="progress"><span /></div>
|
||||
<div class="module-meta">
|
||||
<span>{{ expiringSupports.length }} مورد پیگیری</span>
|
||||
<span>ورود ←</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-for="item in modules"
|
||||
:key="item.key"
|
||||
|
||||
Reference in New Issue
Block a user