From 4e723c31eace9fcef6adfde73ba4a7c6e14e8271 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Tue, 11 Aug 2026 16:05:04 +0330 Subject: [PATCH] feat: UI switch for server access kill switch Add SuperAdmin toggle to cut app/admin access for a sold version with push status feedback. Co-authored-by: Cursor --- src/pages/ServerTenantPage.vue | 92 ++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/pages/ServerTenantPage.vue b/src/pages/ServerTenantPage.vue index 12e093b..12bca7b 100644 --- a/src/pages/ServerTenantPage.vue +++ b/src/pages/ServerTenantPage.vue @@ -54,12 +54,15 @@ const tenant = ref<{ slug: string nameFa: string domain: string + serverAccessBlocked?: boolean } | null>(null) const servers = ref([]) const selectedId = ref(null) const summary = ref(null) const charges = ref([]) const planOptions = ref<{ months: number; label: string }[]>([]) +const accessBlocking = ref(false) +const serverAccessBlocked = ref(false) const form = reactive({ isDedicated: false, @@ -140,6 +143,7 @@ async function loadDetail() { try { const { data } = await api.get(`/servers/tenants/${tenantId.value}`) tenant.value = data.tenant + serverAccessBlocked.value = Boolean(data.tenant?.serverAccessBlocked) servers.value = data.servers || [] planOptions.value = data.planOptions || [] @@ -272,6 +276,48 @@ async function renewServer() { watch(() => route.params.tenantId, loadDetail) onMounted(loadDetail) + +async function onServerAccessToggle(checked: boolean) { + if (!canWrite.value || !tenantId.value) return + accessBlocking.value = true + const previous = serverAccessBlocked.value + serverAccessBlocked.value = checked + try { + const { data } = await api.post(`/servers/tenants/${tenantId.value}/server-access`, { + blocked: checked, + }) + serverAccessBlocked.value = Boolean(data?.tenant?.serverAccessBlocked) + if (tenant.value) { + tenant.value = { + ...tenant.value, + serverAccessBlocked: serverAccessBlocked.value, + } + } + if (data?.push?.ok === false) { + message.warning( + data.push.message || + 'قفل در رجیستری ثبت شد ولی push فوری به سرور نسخه ناموفق بود', + ) + } else if (data?.push?.stub) { + message.warning( + data.push.message || + 'قفل ثبت شد؛ remoteApiToken نیست — push فوری انجام نشد', + ) + } else { + message.success( + serverAccessBlocked.value + ? 'دسترسی اپ/ادمین قطع شد' + : 'دسترسی اپ/ادمین وصل شد', + ) + } + } catch (e: any) { + serverAccessBlocked.value = previous + const msg = e?.response?.data?.message + message.error(Array.isArray(msg) ? msg.join('، ') : msg || 'تغییر دسترسی ناموفق') + } finally { + accessBlocking.value = false + } +}