اعتبار کافی
نزدیک هشدار
diff --git a/src/pages/PluginTenantPage.vue b/src/pages/PluginTenantPage.vue
index 2d2d043..fe72fdc 100644
--- a/src/pages/PluginTenantPage.vue
+++ b/src/pages/PluginTenantPage.vue
@@ -5,7 +5,9 @@ import { message, Modal } from 'ant-design-vue'
import { ArrowRightOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import api from '@/api/http'
import JalaliDatePicker from '@/components/JalaliDatePicker.vue'
+import MoneyInput from '@/components/MoneyInput.vue'
import { formatIranDate, todayIranDateInput, iranDateInputToIso } from '@/utils/datetime'
+import { formatMoney } from '@/utils/money'
type ExpiryLevel = 'healthy' | 'warning' | 'critical' | 'unknown' | 'none'
@@ -96,11 +98,6 @@ function toneClass(level?: ExpiryLevel) {
return level && level !== 'none' ? level : 'unknown'
}
-function formatMoney(value: number | null | undefined) {
- if (value == null) return '—'
- return `${new Intl.NumberFormat('fa-IR').format(value)} ریال`
-}
-
function fillForm(plugin: PluginItem) {
Object.assign(form, {
name: plugin.name || '',
@@ -352,13 +349,7 @@ onMounted(loadDetail)
-
+
@@ -404,13 +395,7 @@ onMounted(loadDetail)
-
+
@@ -479,13 +464,7 @@ onMounted(loadDetail)
-
+
diff --git a/src/pages/ServerPanelPage.vue b/src/pages/ServerPanelPage.vue
index 991d289..30b6082 100644
--- a/src/pages/ServerPanelPage.vue
+++ b/src/pages/ServerPanelPage.vue
@@ -2,7 +2,7 @@
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { message } from 'ant-design-vue'
-import { ArrowRightOutlined, CloudServerOutlined } from '@ant-design/icons-vue'
+import { ArrowRightOutlined, CloudServerOutlined, SearchOutlined } from '@ant-design/icons-vue'
import api from '@/api/http'
type ExpiryLevel = 'dedicated' | 'healthy' | 'warning' | 'critical' | 'unknown'
@@ -27,10 +27,28 @@ type TenantRow = {
const router = useRouter()
const loadingList = ref(false)
const tenants = ref
([])
+const q = ref('')
+
+const filteredTenants = computed(() => {
+ const term = q.value.trim().toLowerCase()
+ if (!term) return tenants.value
+ return tenants.value.filter((t) => {
+ const blob = [
+ t.nameFa,
+ t.domain,
+ t.slug,
+ t.server?.serverName || '',
+ t.server?.expiryLabel || '',
+ ]
+ .join(' ')
+ .toLowerCase()
+ return blob.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?: ExpiryLevel) {
@@ -65,11 +83,23 @@ onMounted(loadTenants)
پنل سرور
- هر نسخه میتواند چند سرور داشته باشد — وضعیت، شارژ و هشدار نزدیک پایان اعتبار
+ هر نسخه میتواند چند سرور داشته باشد — وضعیت، شارژ و هشدار نزدیک پایان اعتبار ·
+ {{ filteredTenants.length }} مورد
+
اختصاصی
اعتبار کافی — سبز
diff --git a/src/pages/ServerTenantPage.vue b/src/pages/ServerTenantPage.vue
index 801d0c8..579e56d 100644
--- a/src/pages/ServerTenantPage.vue
+++ b/src/pages/ServerTenantPage.vue
@@ -5,7 +5,9 @@ import { message, Modal } from 'ant-design-vue'
import { ArrowRightOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import api from '@/api/http'
import JalaliDatePicker from '@/components/JalaliDatePicker.vue'
+import MoneyInput from '@/components/MoneyInput.vue'
import { formatIranDate, todayIranDateInput, iranDateInputToIso } from '@/utils/datetime'
+import { formatMoney } from '@/utils/money'
type ExpiryLevel = 'dedicated' | 'healthy' | 'warning' | 'critical' | 'unknown'
@@ -95,11 +97,6 @@ function toneClass(level?: ExpiryLevel) {
return level || 'unknown'
}
-function formatMoney(value: number | null | undefined) {
- if (value == null) return '—'
- return `${new Intl.NumberFormat('fa-IR').format(value)} ریال`
-}
-
function applyAccount(row: ServerRow | null) {
if (!row) {
summary.value = null
@@ -378,13 +375,7 @@ onMounted(loadDetail)
-
+
@@ -433,13 +424,7 @@ onMounted(loadDetail)
-
+
diff --git a/src/pages/SmsPanelPage.vue b/src/pages/SmsPanelPage.vue
index 07de3c8..4ec5c47 100644
--- a/src/pages/SmsPanelPage.vue
+++ b/src/pages/SmsPanelPage.vue
@@ -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
([])
+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)
پنل پیامکی
-
یک نسخه را انتخاب کنید تا کیف پول و تنظیمات SMS همان نسخه باز شود
+
+ یک نسخه را انتخاب کنید تا کیف پول و تنظیمات SMS همان نسخه باز شود ·
+ {{ filteredTenants.length }} مورد
+
+