feat: add 'Other sites' module for tracking server/plugin/support/SMS of miscellaneous sites

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-07 16:52:32 +03:30
co-authored by Cursor
parent bef5da6239
commit c5e989811a
15 changed files with 268 additions and 63 deletions
+24 -2
View File
@@ -9,7 +9,7 @@ type BalanceLevel = 'healthy' | 'warning' | 'critical' | 'unknown'
type TenantRow = {
id: string
product: 'hamkar' | 'khanegi'
product: 'hamkar' | 'khanegi' | 'other'
slug: string
nameFa: string
domain: string
@@ -44,6 +44,7 @@ const filteredTenants = computed(() => {
const groupedTenants = computed(() => ({
hamkar: filteredTenants.value.filter((t) => t.product === 'hamkar'),
khanegi: filteredTenants.value.filter((t) => t.product === 'khanegi'),
other: filteredTenants.value.filter((t) => t.product === 'other'),
}))
function toneClass(level?: BalanceLevel) {
@@ -188,9 +189,30 @@ onMounted(loadTenants)
<div v-if="!groupedTenants.khanegi.length" class="empty-hint">نسخه‌ای نیست</div>
</div>
</section>
<section v-if="groupedTenants.other.length" class="tenant-group">
<div class="tenant-group-head">
<h3>سایت‌های دیگر</h3>
<span>{{ groupedTenants.other.length }} سایت</span>
</div>
<div class="tenant-grid">
<button
v-for="t in groupedTenants.other"
:key="t.id"
type="button"
class="tenant-card"
:class="toneClass(t.sms?.balanceLevel)"
@click="openTenant(t.id)"
>
<strong>{{ t.nameFa }}</strong>
<span>{{ t.sms?.balanceLabel }}</span>
<small>{{ t.isBlocked ? 'مسدود' : t.domain }}</small>
</button>
</div>
</section>
</div>
<a-empty
v-if="!groupedTenants.hamkar.length && !groupedTenants.khanegi.length"
v-if="!groupedTenants.hamkar.length && !groupedTenants.khanegi.length && !groupedTenants.other.length"
description="نسخه‌ای نیست"
/>
</a-spin>