Files
portal/app/resources/js/stores/tenantStore.ts
T
Дмитрий e1601e7862 feat(billing-v2-c): UI префлайт Task 1.10 — баннер заморозки, индикатор ёмкости, диалог перегрузки
Spec C §3.6/§6.2. Бэкенд: GET /api/billing/balance-status (frozen + capacity + required + дефицит ₽/leads), Pest 6. Фронт: BalanceFrozenBanner (в AppLayout, глобально), BalanceCapacityIndicator (в BillingView под балансом), ProjectLimitOverloadDialog (409-перехват в NewProjectDialog: save-blocked/set-zero), tenantStore + api getBalanceStatus. Vitest +18.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 20:39:21 +03:00

44 lines
1.9 KiB
TypeScript

import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
import * as billingApi from '../api/billing';
import type { BalanceStatus } from '../api/billing';
/**
* Tenant-store: статус баланса текущего тенанта для UI префлайта (Billing v2
* Spec C Task 1.10). Единый источник для глобального баннера заморозки
* (BalanceFrozenBanner в AppLayout) и индикатора ёмкости (BalanceCapacityIndicator
* в BillingView) — чтобы не делать два запроса.
*
* Загружается глобально в AppLayout (load + polling). `load()` молча проглатывает
* ошибку: баннер/индикатор не критичны и не должны валить страницу.
*/
export const useTenantStore = defineStore('tenant', () => {
const status = ref<BalanceStatus | null>(null);
const frozen = computed(() => status.value?.frozen_by_balance_at != null);
const deficitRub = computed(() => status.value?.deficit_rub ?? '0.00');
const deficitLeads = computed(() => status.value?.deficit_leads ?? 0);
const balanceRub = computed(() => status.value?.balance_rub ?? '0.00');
const capacityLeads = computed(() => status.value?.capacity_leads ?? 0);
const requiredLeadsPerDay = computed(() => status.value?.required_leads_per_day ?? 0);
async function load(): Promise<void> {
try {
status.value = await billingApi.getBalanceStatus();
} catch {
// Не критично — оставляем прошлый статус (или null → баннер скрыт).
}
}
return {
status,
frozen,
deficitRub,
deficitLeads,
balanceRub,
capacityLeads,
requiredLeadsPerDay,
load,
};
});